mastra-ai/mastra · error

No CDP session available

Error message

No CDP session available

What it means

Mouse input via CDP requires an attached CDP session for the target page. The library resolves the page for the (explicit or current) thread and asks for its CDP session; if absent it throws. Without the session, Input.dispatchMouseEvent cannot be sent to the browser.

Source

Thrown at browser/stagehand/src/stagehand-browser.ts:1333

    }
  }

  // NOTE: Manual tab switching in browser UI is not fully supported.
  // Stagehand v3 does not track pages opened via browser UI (only pages created through its API).
  // We've requested this feature from Browserbase - see Notion doc for details.

  // ---------------------------------------------------------------------------
  // Event Injection (for Studio live view interactivity)
  // ---------------------------------------------------------------------------

  override async injectMouseEvent(event: MouseEventParams, threadId?: string): Promise<void> {
    // Use the provided threadId, or fall back to the current thread
    const effectiveThreadId = threadId ?? this.getCurrentThread();
    const page = await this.threadManager.getPageForThread(effectiveThreadId);
    const cdpSession = this.getCdpSessionForPage(page);

    if (!cdpSession) {
      throw new Error('No CDP session available');
    }

    // CDP buttons bitmask: left=1, right=2, middle=4
    const buttonMap: Record<string, number> = {
      none: 0,
      left: 1,
      middle: 4,
      right: 2,
    };

    // clickCount should only default to 1 for press/release events; move and wheel use 0
    const defaultClickCount = event.type === 'mousePressed' || event.type === 'mouseReleased' ? 1 : 0;

    await cdpSession.send('Input.dispatchMouseEvent', {
      type: event.type,
      x: event.x,
      y: event.y,
      button: event.button ?? 'none',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Pass the correct threadId or ensure the current thread has an active page with a CDP session
  2. Relaunch/reconnect the browser and retry to re-establish CDP sessions
  3. Perform the action on a page opened through the library's normal API
  4. Fall back to Stagehand-level actions (act/click) that do not need a raw CDP session

Example fix

// before
await browser.cdpMouseMove({ x: 100, y: 200 }, 'thread-B'); // thread-B has no page
// after
await browser.cdpMouseMove({ x: 100, y: 200 }, 'thread-A'); // thread-A owns the page
Defensive patterns

Strategy: try-catch

Validate before calling

if (!browser.isBrowserRunning() || !(await browser.getPage({ threadId }))) {
  throw new Error('Thread has no live page; relaunch before CDP mouse input');
}

Try / catch

try {
  await browser.cdpClick({ x, y }, threadId);
} catch (e) {
  if (e instanceof Error && e.message === 'No CDP session available') {
    await browser.reconnect();
    await browser.cdpClick({ x, y }, threadId);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling CDP-based mouse actions (click at coordinates, etc.) when getCdpSessionForPage(page) returns null — no attached DevTools session for that thread's page, wrong threadId, or the page/session was lost after reconnect.

Common situations: Sending input to a thread whose page was closed; acting after browser reconnect invalidated sessions; using a threadId that has no page while the real page lives on another thread; page opened without CDP attach.

Related errors


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