When Does ego-browser Invalidate CDP Sessions and Clear Preferred Targets?

ego-browser invalidates CDP sessions and clears preferred targets in three scenarios: when a CDP request reports a lost session, when a target is detached or destroyed, and after mutating task-space or ego methods.

The ego-browser package in the citrolabs/ego-lite repository manages a single Chrome DevTools Protocol (CDP) session attached to a preferred target page. Understanding when this session state is reset helps developers debug connection issues and predict runtime behavior during automation workflows.

CDP Session Loss Detection

The runtime automatically detects session failures through error pattern matching in browserCdp(). When a CDP response contains error messages matching /Session (?:with given id )?not found|Target closed|No session/i, the handler immediately triggers recovery.

In package/ego-browser/src/browser-runtime.ts (lines 98-101), the error handler:

// Simplified representation of the error detection logic
if (errorMessage.match(/Session (?:with given id )?not found|Target closed|No session/i)) {
  await invalidateSession();
  // Retry with fresh session automatically
}

This automatic retry mechanism ensures operations continue without manual intervention when a session expires or target crashes.

Target Detachment and Destruction Events

CDP emits lifecycle events when targets change. The runtime subscribes to Target.detachedFromTarget and Target.targetDestroyed events to maintain accurate state.

From browser-runtime.ts (lines 52-64):

// Event handlers clean up when the preferred target goes away
if (detachedTargetId === state.sessionTargetId) {
  invalidateSession();
}

The handler performs two actions:

  • Removes page-event bookkeeping and dialog trackers
  • Invalidates the session only if the detached target matches the current session target

This prevents unnecessary session churn when unrelated targets close.

Task-Space and Ego Method Mutations

State-changing operations explicitly clear both session and preferred target to guarantee clean state. The wrapInvalidating() decorator in package/ego-browser/src/index.ts (lines 81-89) wraps these methods:

Wrapped methods include:

  • useTaskSpace
  • closeTaskSpace
  • createTaskSpace
  • claimTaskSpace
  • createTab
// Example: claimTaskSpace automatically invalidates
await claimTaskSpace('production-env');
// Internally executes:
//   invalidateSession()
//   clearPreferredTarget()

This defensive pattern ensures that task-space isolation translates to fresh CDP connections, preventing cross-contamination between environments.

Core Utility Functions

invalidateSession()

Defined in browser-runtime.ts, this function:

  • Zeros state.sessionId and state.sessionTargetId
  • Clears the session timestamp
  • Drops pending page-event subscriptions
  • Removes dialog event trackers

clearPreferredTarget()

Also in browser-runtime.ts, this simpler utility sets state.preferredTargetId to null. It is always called alongside invalidateSession() in the wrapper functions, though both can be invoked manually in edge cases.

// Manual clearing (rarely needed)
await clearPreferredTarget();
await invalidateSession();

Practical Recovery Patterns

The SDK handles most recovery automatically. Explicit handling is only necessary for custom CDP commands:

// Auto-recovery example: SDK retries internally
await page.goto('https://example.com/long-running-task');

// Custom CDP with manual fallback
try {
  await browserCdp('Runtime.evaluate', { expression: 'window.__custom' });
} catch (e) {
  if (e.message.includes('Session not found')) {
    await invalidateSession();
    // Retry once before surfacing error
  }
}

Summary

  • Automatic invalidation occurs on CDP session errors matching known failure patterns in browserCdp()
  • Event-driven cleanup responds to Target.detachedFromTarget and Target.targetDestroyed events
  • Mutating operations (useTaskSpace, claimTaskSpace, createTab, etc.) proactively clear state via wrapInvalidating()
  • invalidateSession() and clearPreferredTarget() are implemented in browser-runtime.ts and coordinate through index.ts wrappers
  • Manual intervention is rarely required; the runtime prioritizes self-healing connections

Frequently Asked Questions

What error messages trigger automatic session invalidation?

Error messages matching the regex /Session (?:with given id )?not found|Target closed|No session/i trigger automatic invalidation. These indicate the CDP backend has discarded the session or the target process has terminated.

Can I prevent session invalidation during task-space switching?

No. The wrapInvalidating() decorator in index.ts enforces invalidation for all mutating operations to maintain isolation guarantees. This is intentional design—disabling it risks stale target references across task-space boundaries.

How do I check the current session and preferred target state?

The runtime maintains internal state object with sessionId, sessionTargetId, and preferredTargetId fields. These are not directly exposed; instead, rely on the automatic recovery mechanisms or call invalidateSession() and clearPreferredTarget() proactively before critical operations.

Does navigation trigger session invalidation?

Navigation helpers in driver/nav.ts indirectly invoke the same invalidation wrappers, ensuring that page transitions don't leave stale session references. The invalidation occurs through the decorator pattern rather than explicit navigation hooks.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →