v3 lineage: session crash - null context in awaitActivePage when CDP transport drops mid-request (RCA + patch, cherry-pick target for v3 release)
Cross-posted from the archived Python SDK repo: https://github.com/Browserbase/stagehand-python/issues/349 reported a session crash - "Cannot read properties of null (reading 'awaitActivePage')" during act() after rapid CDP cycles. That repo is now archived (nobody can reply there), so filing the RCA + patch here as a cherry-pick target for a v3 release. This is v3 lineage, not a demand on v4 - the python SDK bundles and runs the v3 server, so python users still hit this.
RCA
The null isn't the page - it's the context. In the v3 server lineage (stagehand-server-v3/v3.7.4, tag e0e5c3b):
V3declaresprivate ctx: V3Context | null = null, but the public getter is typed non-null and just returns it.close()setsctxto null (v3.ts:1657), and a dropped CDP transport fires_onCdpClosed->_immediateShutdown->close()immediately.- All five server-v3 routes do
await stagehand.context.awaitActivePage()(act.ts:45, agentExecute.ts:45, extract.ts:46, navigate.ts:43, observe.ts:45).
A rapid act/observe loop eventually drops the transport while an act() is in flight, so act.ts hits stagehand.context.awaitActivePage() with context === null - TypeError, 500, session dead. Non-deterministic because it needs the teardown to land mid-request, which matches the original report.
Fix
The context getter throws a descriptive StagehandError when the session is closed, instead of leaking null into a non-null type - one guard covers all five routes. Typechecks clean on packages/core (tsc --noEmit); no internal this.context callers are affected.
diff --git a/packages/core/lib/v3/v3.ts b/packages/core/lib/v3/v3.ts
index 80962ed..cb0c502 100644
--- a/packages/core/lib/v3/v3.ts
+++ b/packages/core/lib/v3/v3.ts
@@ -82,6 +82,7 @@ import {
CuaModelRequiredError,
StagehandInvalidArgumentError,
StagehandNotInitializedError,
+ StagehandError,
MissingEnvironmentVariableError,
StagehandInitError,
AgentStreamResult,
@@ -1591,6 +1592,17 @@ export class V3 {
/** Expose the current CDP-backed context. */
public get context(): V3Context {
+ // `ctx` is nullable: close() sets it to null, and a dropped CDP transport
+ // nulls it via _onCdpClosed while requests can still be in flight. The
+ // public type is non-null, so without this guard callers crash with
+ // "Cannot read properties of null (reading 'awaitActivePage')".
+ if (!this.ctx) {
+ throw new StagehandError(
+ "`context` is unavailable: the Stagehand session is closed or was never " +
+ "initialized. If the CDP transport dropped mid-request, re-create the " +
+ "session before retrying.",
+ );
+ }
return this.ctx;
}
Built by breken, your AI support engineer - breken.ai finds the bug, proves the fix with unmatched RCA, answers customers in your voice, and keeps your code and support docs clean - this one's on us.
Source: browserbase/stagehand