mastra-ai/mastra · error

No browser context available for screencast

Error message

No browser context available for screencast

What it means

startScreencast needs a live CDP session attached to the currently active page so frames can be captured across tab switches. It asks the thread manager for a fresh CDP session; if no browser context exists for that thread, createFreshCdpSession returns null and this error is thrown instead of failing silently.

Source

Thrown at browser/browser-viewer/src/browser-viewer.ts:270

      activeTabIndex: activeIndex,
    };
  }

  // ---------------------------------------------------------------------------
  // Screencast Support
  // ---------------------------------------------------------------------------

  override async startScreencast(options?: ScreencastOptions): Promise<ScreencastStream> {
    const threadId = options?.threadId ?? this.getCurrentThread();

    // Create CDP session provider that creates FRESH sessions on each call
    // This is critical for tab switching - when reconnecting, we need a CDP session
    // attached to the CURRENT page, not the original page from launch
    const provider: CdpSessionProvider = {
      getCdpSession: async () => {
        const cdpSession = await this.threadManager.createFreshCdpSession(threadId);
        if (!cdpSession) {
          throw new Error('No browser context available for screencast');
        }

        // Return wrapper that implements CdpSessionLike
        return {
          send: async (method: string, params?: Record<string, unknown>) => {
            return cdpSession.send(method as any, params);
          },
          on: (event: string, handler: (params: unknown) => void) => {
            cdpSession.on(event as any, handler);
          },
          off: (event: string, handler: (params: unknown) => void) => {
            cdpSession.off(event as any, handler);
          },
        };
      },
      isBrowserRunning: () => this.isBrowserRunning(threadId),
    };

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure the thread's browser session exists (launch/reconnect) before starting the screencast.
  2. Verify the threadId passed matches a live session; fall back to the viewer's current thread.
  3. Reconnect the thread and retry the screencast after catching this error.
  4. Check no concurrent browser_close is racing the viewer.

Example fix

// before
viewer.startScreencast('stale-thread'); // throws
// after
await viewer.reconnectThread(threadId); // relaunch if missing
await viewer.startScreencast(threadId);
Defensive patterns

Strategy: retry

Validate before calling

const session = await viewer.threadManager.createFreshCdpSession(threadId);
if (!session) {
  await viewer.reconnectThread(threadId); // relaunch before screencast
}
await viewer.startScreencast(threadId);

Type guard

function hasCdpSession<T>(s: T | null | undefined): s is T {
  return s !== null && s !== undefined;
}

Try / catch

try {
  await viewer.startScreencast(threadId);
} catch (err) {
  if (err instanceof Error && err.message === 'No browser context available for screencast') {
    await viewer.reconnectThread(threadId);
    await viewer.startScreencast(threadId); // one retry after relaunch
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling startScreencast for a threadId whose browser session was never launched, was already closed (e.g. via browser_close), or whose browser/page was disposed before the screencast started.

Common situations: Viewer frontend reconnecting after the agent closed its session; screencast started against a stale/expired thread; race where the browser tears down while the viewer boots.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/2400488a3c76117f. Report an issue: GitHub.