{"record":{"id":"d5ceb61b78ce503b","repo":"mastra-ai/mastra","slug":"cdp-session-not-available-for-mouse-injection","errorCode":null,"errorMessage":"CDP session not available for mouse injection","messagePattern":"CDP session not available for mouse injection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"browser/browser-viewer/src/browser-viewer.ts","lineNumber":372,"sourceCode":"        for (const [page, listener] of pageListeners) {\n          page.off('framenavigated', listener);\n        }\n        pageListeners.clear();\n      });\n    }\n\n    await stream.start();\n    return stream;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Input Injection\n  // ---------------------------------------------------------------------------\n\n  override async injectMouseEvent(params: MouseEventParams, threadId?: string): Promise<void> {\n    const cdpSession = await this.threadManager.getCdpSessionForThread(threadId ?? this.getCurrentThread());\n    if (!cdpSession) {\n      throw new Error('CDP session not available for mouse injection');\n    }\n\n    await cdpSession.send('Input.dispatchMouseEvent', params);\n  }\n\n  override async injectKeyboardEvent(params: KeyboardEventParams, threadId?: string): Promise<void> {\n    const cdpSession = await this.threadManager.getCdpSessionForThread(threadId ?? this.getCurrentThread());\n    if (!cdpSession) {\n      throw new Error('CDP session not available for keyboard injection');\n    }\n\n    await cdpSession.send('Input.dispatchKeyEvent', params);\n  }\n\n  // ---------------------------------------------------------------------------\n  // Tools (CLI agents don't use SDK tools - they use workspace commands)\n  // ---------------------------------------------------------------------------\n","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/browser/browser-viewer/src/browser-viewer.ts#L354-L390","documentation":"injectMouseEvent dispatches mouse events over a CDP session bound to the thread's active page. If getCdpSessionForThread resolves no session (never launched, closed, or page detached), there is nowhere to send Input.dispatchMouseEvent, so the method throws.","triggerScenarios":"Calling injectMouseEvent when the thread has no running browser session, after the session/page was closed, or with a threadId that never launched a browser; also when the default current thread has no session.","commonSituations":"Remote viewer clicking a page after the agent session timed out; passing undefined threadId while the current thread lacks a session; CDP detachment after tab close or crash.","solutions":["Reconnect or relaunch the browser session for the target thread before injecting.","Pass an explicit threadId with a live session instead of relying on defaults.","Check session availability (or catch) and recreate the session, then retry.","Treat browser_close as invalidating pending injections."],"exampleFix":"// before\nawait viewer.injectMouseEvent(params, 'unknown-thread'); // throws\n// after\nif (!(await viewer.threadManager.getCdpSessionForThread(threadId))) {\n  await viewer.reconnectThread(threadId);\n}\nawait viewer.injectMouseEvent(params, threadId);","handlingStrategy":"validation","validationCode":"const session = await viewer.threadManager.getCdpSessionForThread(threadId ?? viewer.getCurrentThread());\nif (!session) {\n  await viewer.reconnectThread(threadId); // or show a 'reconnecting' UI state\n} else {\n  await viewer.injectMouseEvent(params, threadId);\n}","typeGuard":"type CdpSession = NonNullable<Awaited<ReturnType<typeof viewer.threadManager.getCdpSessionForThread>>>;\nfunction isCdpSessionAvailable(s: CdpSession | null | undefined): s is CdpSession {\n  return s != null;\n}","tryCatchPattern":"try {\n  await viewer.injectMouseEvent(params, threadId);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('not available for mouse injection')) {\n    await viewer.reconnectThread(threadId);\n    await viewer.injectMouseEvent(params, threadId);\n    return;\n  }\n  throw err;\n}","preventionTips":["Check session availability before each injection batch.","Pass explicit threadIds instead of relying on viewer current-thread defaults.","Treat browser_close as invalidating pending injections in the UI.","Reconnect on CDP detach events rather than injecting into dead sessions."],"tags":["browser","cdp","input-injection","missing-session"],"backgroundTag":"cdp-session-unavailable","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}