How ego-lite Handles SESSION_LOST Errors During CDP Communication
ego-lite intercepts SESSION_LOST errors using a regex matcher in the low-level CDP dispatcher and automatically recovers by invalidating the stale session, acquiring a new CDP session via Target.attachToTarget, and retrying the original command transparently.
When browser tabs close, reload, or get reclaimed during long-running automation tasks, the underlying Chrome DevTools Protocol (CDP) session becomes invalid. The ego-lite runtime implements a resilient error-handling strategy that detects these SESSION_LOST conditions and manages session recovery without requiring manual intervention from calling code.
Detecting SESSION_LOST Errors
The detection logic resides in package/ego-browser/src/browser-runtime.ts. When a CDP request is issued, the low-level rawCdp helper forwards the command to globalThis.ego.sendCDPMessage. If the browser reports a missing session, the error message is tested against the SESSION_LOST regular expression.
This regex matches fatal session states including phrases like "Session … not found", "Target closed", or "No session" (lines 9-11). By catching these patterns at the transport layer, ego-lite distinguishes between transient network failures and terminal session loss that requires re-attachment.
Automatic Recovery Mechanism
The public browserCdp function wraps rawCdp in a try / catch block to implement transparent recovery. When a caught error satisfies the SESSION_LOST test and the request was not explicitly targeting a specific session ID, the runtime executes a three-step recovery process:
- Invalidate stale state by calling
invalidateSession(), which clears the cached session ID and any pending dialog state (lines 46-53). - Acquire a fresh session via
ensureSession(), which handles the negotiation of a new CDP attachment (lines 107-119). - Retry the original command using the newly created session ID, returning the result to the original caller (lines 99-102).
This flow ensures that page-level CDP commands survive tab reloads or closures without throwing errors to higher-level helpers like navigation or element resolution functions.
Session Lifecycle and Re-Attachment
The ensureSession() function manages the lifecycle of the CDP session with a time-to-live (TTL) of approximately 2 seconds. When invoked, it first checks whether the cached session is still valid. If the TTL has expired or the session is missing, it performs the following actions:
- Enumerates open browser tabs using
ego.listTabs()and selects the preferred or active tab. - Attaches to the target using the
Target.attachToTargetCDP method. - Enables page-level events by issuing
Page.enableso that downstream helpers (such as dialog trackers) receive proper events (lines 125-136).
After successful attachment, the new session ID is cached and the original CDP command is reissued with this fresh context.
Code Example: Resilient CDP Calls
The following patterns demonstrate automatic versus explicit session handling:
import { browserCdp } from "ego-browser";
// Page-level call: ego-lite auto-recovers if the target session vanished.
await browserCdp("Runtime.evaluate", { expression: "document.title" });
import { ensureSession, browserCdp } from "ego-browser";
// Explicit session usage bypasses auto-recovery.
const session = await ensureSession();
try {
await browserCdp("Runtime.evaluate", { expression: "1+1" }, session);
} catch (e) {
// e may still be a SESSION_LOST error because we requested a fixed session.
// Manual re-attachment logic would be required here.
}
In the first example, any SESSION_LOST error triggers the automatic invalidation and retry logic. In the second example, because a specific session object is provided, the runtime assumes the caller manages session lifecycle and does not intercept the error.
Summary
- Detection occurs in
rawCdp(src/browser-runtime.ts) using a regex that matches "Session not found" and similar CDP error strings. - Recovery is handled by
browserCdp, which catches qualifying errors and orchestrates session replacement. - State cleanup via
invalidateSession()removes stale session IDs and dialog state before re-attachment. - Session creation through
ensureSession()enforces a 2-second TTL and usesTarget.attachToTargetto establish a new CDP connection. - Transparency is maintained for page-level calls, while explicit session usage requires manual error handling.
Frequently Asked Questions
What triggers a SESSION_LOST error in ego-lite?
A SESSION_LOST error occurs when the CDP target (browser tab) closes, reloads, or detaches unexpectedly. The error surfaces through Chrome DevTools Protocol messages such as "Session not found" or "Target closed", which are matched by the regex in src/browser-runtime.ts lines 9-11 according to the citrolabs/ego-lite source code.
How does ego-lite differ between page-level and explicit session CDP calls?
Page-level calls omit a specific session ID, allowing browserCdp to trigger automatic recovery on session loss. Explicit session calls pass a specific session object returned by ensureSession(), which bypasses the retry logic and requires the caller to handle SESSION_LOST exceptions manually.
What is the session TTL in ego-lite?
The cached session ID has a TTL of approximately 2 seconds. The ensureSession() function checks this TTL before reusing a cached session; if expired, it automatically enumerates tabs and attaches to a new target via Target.attachToTarget.
Does ego-lite notify the caller when it recovers from SESSION_LOST?
No, the recovery is transparent to the caller. When browserCdp intercepts a session loss, it invalidates the old session, creates a new one, and returns the result of the retried command without throwing an exception or logging a warning to the calling code.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →