mastra-ai/mastra · error
CDP session not available for mouse injection
Error message
CDP session not available for mouse injection
What it means
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.
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.
Example fix
// before
await viewer.injectMouseEvent(params, 'unknown-thread'); // throws
// after
if (!(await viewer.threadManager.getCdpSessionForThread(threadId))) {
await viewer.reconnectThread(threadId);
}
await viewer.injectMouseEvent(params, threadId); Defensive patterns
Strategy: validation
Validate before calling
const session = await viewer.threadManager.getCdpSessionForThread(threadId ?? viewer.getCurrentThread());
if (!session) {
await viewer.reconnectThread(threadId); // or show a 'reconnecting' UI state
} else {
await viewer.injectMouseEvent(params, threadId);
} Type guard
type CdpSession = NonNullable<Awaited<ReturnType<typeof viewer.threadManager.getCdpSessionForThread>>>;
function isCdpSessionAvailable(s: CdpSession | null | undefined): s is CdpSession {
return s != null;
} Try / catch
try {
await viewer.injectMouseEvent(params, threadId);
} catch (err) {
if (err instanceof Error && err.message.includes('not available for mouse injection')) {
await viewer.reconnectThread(threadId);
await viewer.injectMouseEvent(params, threadId);
return;
}
throw err;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- CDP session not available for keyboard injection
- No browser context available for screencast
- Failed to fetch CDP version info from
- Invalid browser configuration: "cdpUrl" and "scope…
- Invalid browser configuration: "cdpUrl" cannot be used with
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d5ceb61b78ce503b.
Report an issue: GitHub.
Appendix: source
Thrown at browser/browser-viewer/src/browser-viewer.ts:372
for (const [page, listener] of pageListeners) {
page.off('framenavigated', listener);
}
pageListeners.clear();
});
}
await stream.start();
return stream;
}
// ---------------------------------------------------------------------------
// Input Injection
// ---------------------------------------------------------------------------
override async injectMouseEvent(params: MouseEventParams, threadId?: string): Promise<void> {
const cdpSession = await this.threadManager.getCdpSessionForThread(threadId ?? this.getCurrentThread());
if (!cdpSession) {
throw new Error('CDP session not available for mouse injection');
}
await cdpSession.send('Input.dispatchMouseEvent', params);
}
override async injectKeyboardEvent(params: KeyboardEventParams, threadId?: string): Promise<void> {
const cdpSession = await this.threadManager.getCdpSessionForThread(threadId ?? this.getCurrentThread());
if (!cdpSession) {
throw new Error('CDP session not available for keyboard injection');
}
await cdpSession.send('Input.dispatchKeyEvent', params);
}
// ---------------------------------------------------------------------------
// Tools (CLI agents don't use SDK tools - they use workspace commands)
// ---------------------------------------------------------------------------
View on GitHub (pinned to 75dd419e61)