Hmbown/CodeWhale · error · ServerError
unsupported_on_backend
unsupported_on_backend
Error message
"${name}" is not implemented on the ${computer.platform ?? computer.transport} backend What it means
The Codewhale Computer Use MCP server resolves each tool call to a platform-specific backend (macOS/Windows/accessibility/remote via computer.transport). If the resolved backend object does not expose the method that implements the requested tool, the server refuses the call with code 'unsupported_on_backend' instead of dispatching it and failing opaquely. It means the tool exists in the catalog but is genuinely not implemented on the backend currently bound to the computer.
Solutions
- Check which computer/binding the tool call targets and switch to a computer whose platform/transport implements the tool (call computer_list to see available computers).
- Consult the tool catalog to confirm the tool is supported for the current transport (REMOTE_TOOLS allow-list for remote agents); pick a supported equivalent tool.
- Update/restart the Computer Use helper app so the backend build matches the plugin (see the stale-version note the server emits) — a missing method often means an old build.
- If this is your own backend contribution, implement the missing backend[BACKEND_METHOD[tool]] method for that platform.
Example fix
// before
call({ name: 'set_value', arguments: { computer_id: 'remote-agent-1', target: { type: 'element', index: 4 } } })
// after — use a computer whose platform implements the tool
call({ name: 'set_value', arguments: { computer_id: 'local-mac-1', target: { type: 'element', index: 4 } } }) Defensive patterns
Strategy: try-catch
Validate before calling
// Check the tool is dispatched to a backend that implements it (client-side knowledge)
const remote = computer.transport === 'ssh';
if (remote && !REMOTE_TOOLS.has(toolName)) throw new Error(`${toolName} is not available on remote computers`); Type guard
function backendSupports(backend, tool, methodMap) { return typeof backend?.[methodMap[tool] ?? tool] === 'function'; } Try / catch
try {
const res = await callTool({ name: tool, arguments: args });
} catch (e) {
if (e?.code === 'unsupported_on_backend') {
// switch computer or fall back to a supported tool
const computers = await callTool({ name: 'computer_list', arguments: {} });
console.error(`${e.message}; available: ${JSON.stringify(computers)}`);
} else throw e;
} Prevention
- Call computer_list first and pick a computer whose platform/transport supports the tool
- Keep the Computer Use helper app current — restart the app after plugin updates so backend methods exist
- Maintain a per-transport capability list in your agent planner and filter tool choices by it
- Handle code 'unsupported_on_backend' by retrying on a different computer rather than repeating the call
When it happens
Trigger: Calling a tool whose BACKEND_METHOD is missing on the active backend — e.g. calling an accessibility-only tool on a computer whose transport is a remote agent, or calling a platform-specific action on a backend stub without that method. computer.platform ?? computer.transport is used to name the backend in the message.
Common situations: 1) Targeting a remote/ssh computer with a tool the remote agent allow-list does not cover. 2) A stub/mock or partial backend used in development or tests lacking that tool's method. 3) Version skew where an older helper app does not yet implement a newly added tool. 4) Wrong computer selected (platform mismatch) in a multi-computer session.
Related errors
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/57d7a54d31a345d0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/mcp/server.mjs:997
}
}
if (backendMethod === "zoom") bindZoomRaster(computer, zoomParent, args.region, ex.filesLocal ? data?.file ?? data?.path : null);
if (name === "get_app_state") {
data = observeState(computer, wireArgs.app_ref, data, args);
}
if (backendMethod === "probe") Object.assign(data, { via: ex.kind, app: ex.app ?? null });
if (backendMethod === "probe" && data?.app?.version && data.app.version !== APP_VERSION) {
// The helper owns the modules it loaded at start, so a plugin update
// without a helper restart serves the previous build's behavior. Say
// so instead of letting the agent debug a build that is not running.
data.app.bundled_version = APP_VERSION;
data.app.stale = true;
data.note = [data.note, `The running helper reports ${data.app.version} but this plugin is ${APP_VERSION} — restart the Codewhale Computer Use app to load the current build.`].filter(Boolean).join(" ");
}
} else {
const backend = await getBackend(computer, binding);
if (typeof backend[backendMethod] !== "function") {
throw new ServerError("unsupported_on_backend", `"${name}" is not implemented on the ${computer.platform ?? computer.transport} backend`);
}
const resolve = typeof backend.resolve_element === "function" ? (req) => backend.resolve_element(req) : null;
const prepared = await prepareArgs(computer, name, args, resolve, sink);
throwIfAborted();
await assertCurrentRoute(computer, binding);
if (controlStopped && !READ_ONLY_TOOLS.has(name)) throw new ServerError("control_stopped", "stop_computer_control is active; no further actions are permitted this session");
inFlight++;
try {
dispatched = true;
data = name === "type"
? await invokeType((tool, a) => backend[BACKEND_METHOD[tool] ?? tool](a), prepared)
: await backend[backendMethod](prepared);
} finally {
inFlight--;
}
await assertCurrentRoute(computer, binding, true);
if (Array.isArray(data)) data = { items: data }; // keep receipts objects
if (name === "screenshot") bindRaster(computer, data);View on GitHub (pinned to 73e0f67d83)