musistudio/claude-code-router · error · Error

A valid browser automation session is required.

Error message

A valid browser automation session is required.

What it means

Thrown by requireSession when resolveOptionalSession cannot produce an AttachedSession from the arguments. Some tools operate only in the context of an established automation session; passing no session object, or one whose ref fails to parse or resolve, triggers this error.

Source

Thrown at packages/electron/src/main/browser-automation-mcp.ts:1213

  }

  private async createTab(args: Record<string, unknown>): Promise<unknown> {
    const state = await this.ensureBrowserOpen();
    const session = this.resolveOptionalSession(args);
    this.assertCanMutate(session);
    const previousActiveTabId = state.activeTabId;
    const tab = builtInBrowserService.createAutomationTab(readString(args.url) || undefined);
    if (args.activate === false && previousActiveTabId) {
      builtInBrowserService.selectAutomationTab(previousActiveTabId);
    }
    const nextState = builtInBrowserService.getAutomationState();
    return summarizeTab(requiredTabState(nextState, tab.id), nextState.activeTabId);
  }

  private requireSession(args: Record<string, unknown>): AttachedSession {
    const session = this.resolveOptionalSession(args);
    if (!session) {
      throw new Error("A valid browser automation session is required.");
    }
    return session;
  }

  private resolveOptionalSession(args: Record<string, unknown>): AttachedSession | undefined {
    const ref = readSessionRef(args.session);
    if (!ref) {
      return undefined;
    }
    const existing = this.sessions.get(ref.sessionId);
    if (existing) {
      if (existing.ref.tabId !== ref.tabId) {
        throw new Error("Browser automation session tabId does not match the attached session.");
      }
      return existing;
    }
    const state = builtInBrowserService.getAutomationState();
    if (!state.tabs.some((tab) => tab.id === ref.tabId)) {

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Run the tool that establishes the session first and echo its returned session object into subsequent calls.
  2. Ensure the session object has valid sessionId and tabId fields.
  3. If the tab was closed, re-create/re-attach the session before retrying.

Example fix

// before
await call("browser_session_tool", {});

// after
const { session } = await call("browser_attach", { tabId });
await call("browser_session_tool", { session });
Defensive patterns

Strategy: validation

Validate before calling

if (!isAttachedSession(args.session)) { const { session } = await call("browser_attach", { tabId }); args.session = session; }
await call(sessionTool, args);

Type guard

function isAttachedSession(v: unknown): v is { ref: { sessionId: string; tabId: string } } { return typeof v === "object" && v !== null && typeof (v as any).ref?.sessionId === "string" && typeof (v as any).ref?.tabId === "string"; }

Try / catch

try { await call(sessionTool, args); } catch (e) { if (e instanceof Error && e.message.includes("valid browser automation session is required")) { const { session } = await call("browser_attach", { tabId }); await call(sessionTool, { ...args, session }); } else throw e; }

Prevention

When it happens

Trigger: Calling a session-scoped tool with arguments lacking a valid session field — the session value is not a record, has no usable sessionId/tabId, or the referenced session/tab lookup failed inside resolveOptionalSession.

Common situations: Scripts skip the attach/creation step and jump straight to a session-only tool; session state was cleared (e.g. tab closed removed its sessions) while the caller keeps the old ref.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/25d7e90d40029b71. Report an issue: GitHub.