can1357/oh-my-pi · error · ToolError
Computer session tool bridge is unavailable
Error message
Computer session tool bridge is unavailable
What it means
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.
Source
Thrown at packages/coding-agent/src/tools/computer/supervisor.ts:157
readonly #callSessionTool: ComputerSessionToolCaller;
readonly #timeouts: ComputerSupervisorTimeouts;
#worker?: ComputerWorkerHandle;
#startPromise?: Promise<void>;
#startReject?: (error: unknown) => void;
#startResolve?: () => void;
#latestCapabilities?: DesktopCapabilities;
#pending = new Map<string, PendingRun>();
#nextId = 0;
#closed = false;
#unsubscribeMessage?: () => void;
#unsubscribeError?: () => void;
constructor(
session: ToolSession,
createWorker: ComputerWorkerFactory = spawnComputerWorker,
timeouts: ComputerSupervisorTimeouts = DEFAULT_TIMEOUTS,
callSessionTool: ComputerSessionToolCaller = async () => {
throw new ToolError("Computer session tool bridge is unavailable");
},
) {
this.#session = session;
this.#createWorker = createWorker;
this.#timeouts = timeouts;
this.#callSessionTool = callSessionTool;
}
async capabilities(): Promise<DesktopCapabilities | undefined> {
return this.#latestCapabilities;
}
async run(
code: string,
timeoutMs: number,
snapshot: ComputerSessionSnapshot,
signal?: AbortSignal,
): Promise<ComputerRunOk> {View on GitHub (pinned to 9690622007)
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.
Example fix
// before const supervisor = new ComputerSupervisor(session, spawnComputerWorker); // after const supervisor = new ComputerSupervisor(session, spawnComputerWorker, DEFAULT_TIMEOUTS, (tool, args) => session.callTool(tool, args), );
Defensive patterns
Strategy: validation
Validate before calling
// at construction site, ensure the bridge is provided
if (typeof callSessionTool !== "function") {
throw new Error("ComputerSupervisor requires a callSessionTool bridge");
}
const supervisor = new ComputerSupervisor(session, createWorker, timeouts, callSessionTool); Try / catch
try {
await supervisor.run(code, timeout, snapshot, signal);
} catch (err) {
if (err instanceof ToolError && /session tool bridge is unavailable/.test(err.message)) {
logger.error("ComputerSupervisor built without session tool bridge — fix DI wiring");
throw err;
} else throw err;
} Prevention
- 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.
When it happens
Trigger: Constructing ComputerSupervisor without the third callSessionTool argument and then running computer code that issues a session tool call.
Common situations: 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.
Related errors
- Computer session is closed
- Assertion failed
- ${error.message} (rethrown as ToolError from StructuredSubag
- JS eval worker smoke fell back from the isolated subprocess
- Plan mode is not active.
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/5a000d6a13c128cc.
Report an issue: GitHub.