Hmbown/CodeWhale · error · ServerError
remote_error
remote_error
Error message
${r.error?.message ?? "remote agent failed"} What it means
When a tool is dispatched to a remote agent over the persistent channel (ssh --serve etc.), a reply with ok:false is converted into a ServerError. The code defaults to remote_error but the agent's own error code and message are forwarded verbatim, so this error is a passthrough of a failure that happened on the remote side.
Solutions
- Read the forwarded r.error.message in the thrown error — it names the actual remote failure
- Upgrade the remote agent if the tool/code is unsupported (old agent without --serve features)
- Re-establish the remote session/channel and retry if the agent reported a transient failure
- Reproduce the failing precondition locally to confirm the remote environment state
Example fix
// before
const r = await remoteCall(...); // returns { ok: false, error: { message: "no window" } }
// after — ensure the target window/app exists remotely, then retry
await getAppState({}); // verify remote state before re-issuing the action Defensive patterns
Strategy: try-catch
Validate before calling
// no local check can predict remote failures; verify remote state before acting:
const st = await getAppState({ computer }); // confirm the target exists remotely first Type guard
const isStructuredError = (r) => r && r.ok === false && typeof r.error?.message === "string";
Try / catch
try { await remoteAction(...) } catch (e) { if (e.code === "remote_error") { log(e.message); if (isTransient(e.message)) await reconnectAndRetry(); } else throw e; } Prevention
- Log the forwarded remote message verbatim for diagnosis
- Keep the remote agent version compatible with the server's tool set
- Check remote app/window state before dispatching actions
- Treat remote errors as environment problems, not client bugs
When it happens
Trigger: Any remote tool call where the remote agent returns { ok: false } — remote-side precondition failures, unknown tools on the agent, backend errors, or timeouts surfaced by the agent as a structured error reply.
Common situations: Old agent versions not supporting a requested tool; remote machine state changed (window closed, app quit); remote backend permission or environment problems; network-induced agent failures reported as structured errors.
Related errors
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/87689bb91360f846.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/mcp/server.mjs:964
};
const resolve = async (req) => {
const rep = await remoteCall({ tool: "resolve_element", args: req }, { timeoutMs: 30_000 });
if (!rep?.ok) return { found: false, element: null, reason: rep?.error?.code ?? "remote_error" };
return rep.data;
};
const wireArgs = await prepareArgs(computer, name, args, resolve, sink);
throwIfAborted();
await assertCurrentRoute(computer, binding);
// Re-check the kill switch: a stop that arrived while the executor was
// being resolved still blocks this dispatch.
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;
const timeoutMs = backendMethod.startsWith("recording") || backendMethod === "get_app_state" ? 60_000 : 30_000;
const invoke = async (tool, a) => {
const r = await remoteCall({ tool, args: a }, { timeoutMs });
if (!r.ok) throw new ServerError(r.error?.code ?? "remote_error", r.error?.message ?? "remote agent failed");
return r.data;
};
data = name === "type" ? await invokeType(invoke, wireArgs) : await invoke(backendMethod, wireArgs);
} finally {
inFlight--;
}
await assertCurrentRoute(computer, binding, true);
if (Array.isArray(data)) data = { items: data };
if ((backendMethod === "screenshot" || backendMethod === "zoom") && data?.file) {
if (ex.filesLocal) bindRaster(computer, data);
else {
// Raster lives on the remote machine; bind geometry for coordinate mapping.
bindRaster(computer, { ...data, file: null });
data.note = "file lives on the remote computer; pull it with scp if you need the bytes locally";
}
}
if (backendMethod === "zoom") bindZoomRaster(computer, zoomParent, args.region, ex.filesLocal ? data?.file ?? data?.path : null);
if (name === "get_app_state") {View on GitHub (pinned to 73e0f67d83)