{"record":{"id":"a183d315bd18f82f","repo":"mastra-ai/mastra","slug":"cdp-session-not-available-for-keyboard-injection","errorCode":null,"errorMessage":"CDP session not available for keyboard injection","messagePattern":"CDP session not available for keyboard injection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"browser/browser-viewer/src/browser-viewer.ts","lineNumber":381,"sourceCode":"  }\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\n  getTools(): Record<string, Tool> {\n    // CLI agents use workspace_execute_command with CLI skills\n    // No SDK tools needed\n    return {};\n  }\n}\n","sourceCodeStart":363,"sourceCodeEnd":397,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/browser/browser-viewer/src/browser-viewer.ts#L363-L397","documentation":"injectKeyboardEvent sends Input.dispatchKeyEvent over a CDP session attached to the thread's page. When no CDP session exists for the given (or current) thread, the event has no target, so the method throws instead of failing silently.","triggerScenarios":"Calling injectKeyboardEvent when the thread's browser session does not exist, was closed, or the CDP session detached; same conditions as mouse injection but for keyboard events.","commonSituations":"Typing in the viewer after the agent session expired; injecting into a default current thread with no session; concurrent browser_close invalidating the session mid-interaction.","solutions":["Ensure a live browser session exists for the thread; reconnect before injecting.","Pass an explicit threadId with a live session rather than relying on the current thread.","Catch the error, re-establish the CDP session, and retry the keystroke.","Verify no concurrent close/dispose is racing the injection."],"exampleFix":"// before\nawait viewer.injectKeyboardEvent({ type: 'keyDown', key: 'Enter' }); // throws if no session\n// after\nif (!(await viewer.threadManager.getCdpSessionForThread(threadId))) {\n  await viewer.reconnectThread(threadId);\n}\nawait viewer.injectKeyboardEvent({ type: 'keyDown', key: 'Enter' }, threadId);","handlingStrategy":"try-catch","validationCode":"const session = await viewer.threadManager.getCdpSessionForThread(threadId ?? viewer.getCurrentThread());\nif (!session) throw new Error('Reconnect thread before keyboard injection');\nawait viewer.injectKeyboardEvent(params, threadId);","typeGuard":"function canInjectKeyboard(s: unknown): boolean {\n  return s !== null && s !== undefined && typeof (s as { send?: unknown }).send === 'function';\n}","tryCatchPattern":"try {\n  await viewer.injectKeyboardEvent(params, threadId);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('not available for keyboard injection')) {\n    await viewer.reconnectThread(threadId);\n    return viewer.injectKeyboardEvent(params, threadId);\n  }\n  throw err;\n}","preventionTips":["Guard keyboard injection with a session-existence check like the mouse path.","Route all input injection through a helper that reconnects on missing sessions.","Disable viewer input controls when the session is unavailable.","Avoid injecting during teardown/dispose windows."],"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-30T03:17:51.788Z"}