{"record":{"id":"5a000d6a13c128cc","repo":"can1357/oh-my-pi","slug":"computer-session-tool-bridge-is-unavailable","errorCode":null,"errorMessage":"Computer session tool bridge is unavailable","messagePattern":"Computer session tool bridge is unavailable","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/computer/supervisor.ts","lineNumber":157,"sourceCode":"\treadonly #callSessionTool: ComputerSessionToolCaller;\n\treadonly #timeouts: ComputerSupervisorTimeouts;\n\t#worker?: ComputerWorkerHandle;\n\t#startPromise?: Promise<void>;\n\t#startReject?: (error: unknown) => void;\n\t#startResolve?: () => void;\n\t#latestCapabilities?: DesktopCapabilities;\n\t#pending = new Map<string, PendingRun>();\n\t#nextId = 0;\n\t#closed = false;\n\t#unsubscribeMessage?: () => void;\n\t#unsubscribeError?: () => void;\n\n\tconstructor(\n\t\tsession: ToolSession,\n\t\tcreateWorker: ComputerWorkerFactory = spawnComputerWorker,\n\t\ttimeouts: ComputerSupervisorTimeouts = DEFAULT_TIMEOUTS,\n\t\tcallSessionTool: ComputerSessionToolCaller = async () => {\n\t\t\tthrow new ToolError(\"Computer session tool bridge is unavailable\");\n\t\t},\n\t) {\n\t\tthis.#session = session;\n\t\tthis.#createWorker = createWorker;\n\t\tthis.#timeouts = timeouts;\n\t\tthis.#callSessionTool = callSessionTool;\n\t}\n\n\tasync capabilities(): Promise<DesktopCapabilities | undefined> {\n\t\treturn this.#latestCapabilities;\n\t}\n\n\tasync run(\n\t\tcode: string,\n\t\ttimeoutMs: number,\n\t\tsnapshot: ComputerSessionSnapshot,\n\t\tsignal?: AbortSignal,\n\t): Promise<ComputerRunOk> {","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/computer/supervisor.ts#L139-L175","documentation":"ComputerSupervisor's constructor takes a callSessionTool dependency; its default value is a function that always throws this ToolError. The default exists only to make the parameter explicit — if the supervisor reaches a point where it needs to invoke a session-side tool and no real bridge was injected, this error surfaces, meaning the supervisor was constructed without wiring the session tool bridge.","triggerScenarios":"Constructing ComputerSupervisor without the third callSessionTool argument and then running computer code that issues a session tool call.","commonSituations":"Tests or scripts instantiate the supervisor directly with only (session, workerFactory, timeouts); a DI/wiring refactor dropped the bridge argument; production bootstrap forgot to pass the session-tool adapter.","solutions":["Pass a real callSessionTool implementation (the adapter that forwards into the ToolSession) as the constructor's third argument.","Check the supervisor construction site in the computer tool bootstrap and restore the bridge wiring.","In tests, inject a stub bridge if session tool calls are not expected, and assert none occur."],"exampleFix":"// before\nconst supervisor = new ComputerSupervisor(session, spawnComputerWorker);\n\n// after\nconst supervisor = new ComputerSupervisor(session, spawnComputerWorker, DEFAULT_TIMEOUTS, (tool, args) =>\n  session.callTool(tool, args),\n);","handlingStrategy":"validation","validationCode":"// at construction site, ensure the bridge is provided\nif (typeof callSessionTool !== \"function\") {\n  throw new Error(\"ComputerSupervisor requires a callSessionTool bridge\");\n}\nconst supervisor = new ComputerSupervisor(session, createWorker, timeouts, callSessionTool);","typeGuard":null,"tryCatchPattern":"try {\n  await supervisor.run(code, timeout, snapshot, signal);\n} catch (err) {\n  if (err instanceof ToolError && /session tool bridge is unavailable/.test(err.message)) {\n    logger.error(\"ComputerSupervisor built without session tool bridge — fix DI wiring\");\n    throw err;\n  } else throw err;\n}","preventionTips":["Make callSessionTool a required constructor argument in your wrappers so omission fails at compile/lint time.","Add a boot-time wiring test that constructs the supervisor as production does.","Never rely on library default parameter values for runtime-critical dependencies."],"tags":["dependency-injection","wiring","computer-tool","tool-error"],"backgroundTag":"missing-dependency-injection","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}