can1357/oh-my-pi · error · ToolError
Invalid cmux socket response: expected object
Error message
Invalid cmux socket response: expected object
What it means
After a reply line parses as JSON, #parseResponse requires the payload to be a JSON object. Scalars, arrays, strings, or null payloads cannot carry the {ok, result, error} envelope, so this ToolError is thrown. It signals the peer speaks JSON but not the cmux response envelope.
Source
Thrown at packages/coding-agent/src/tools/browser/cmux/socket-client.ts:394
line = line.slice(0, -1);
}
const waiter = this.#lineWaiters.shift();
waiter?.resolve(line);
}
}
#parseResponse(line: string): Record<string, unknown> {
if (line.startsWith("ERROR:")) {
throw new ToolError(line);
}
let payload: unknown;
try {
payload = JSON.parse(line);
} catch (err) {
throw new ToolError(`Invalid cmux socket JSON response: ${err instanceof Error ? err.message : String(err)}`);
}
if (!payload || typeof payload !== "object") {
throw new ToolError("Invalid cmux socket response: expected object");
}
const response = payload as { ok?: unknown; result?: unknown; error?: CmuxErrorPayload };
if (response.ok === true) {
return (response.result ?? {}) as Record<string, unknown>;
}
if (response.ok === false) {
throw new ToolError(formatCmuxError(response.error));
}
throw new ToolError("Invalid cmux socket response: missing ok flag");
}
#handleSocketFailure(err: Error): void {
if (this.#disposed) return;
this.#connected = false;
this.#connectPromise = null;
this.#rejectAll(new ToolError(`cmux socket error: ${err.message}`));
this.#socket?.destroy();
this.#socket = null;View on GitHub (pinned to 9690622007)
Solutions
- Confirm the endpoint is the cmux daemon and the method is expected to return the {ok,...} envelope
- Upgrade or downgrade the daemon so client/server protocol versions align
- Inspect the raw reply (enable socket logging) to see what shape came back, then correct the caller or file a daemon bug
Defensive patterns
Strategy: type-guard
Type guard
function isCmuxEnvelope(v: unknown): v is { ok: boolean; result?: unknown; error?: { code?: string; message?: string; details?: unknown } } {
return typeof v === "object" && v !== null && "ok" in v && typeof (v as { ok: unknown }).ok === "boolean";
} Try / catch
try {
return await client.request(method, params);
} catch (err) {
if (err instanceof ToolError && err.message === "Invalid cmux socket response: expected object") {
// peer is not speaking the cmux envelope: check endpoint and protocol version
}
throw err;
} Prevention
- Verify the endpoint is the cmux daemon, not another JSON service sharing the path/port
- Run matching client/daemon versions so the {ok,result,error} envelope is guaranteed
- If you wrap CmuxSocketClient, validate responses with an isCmuxEnvelope-style guard before consuming
When it happens
Trigger: Daemon returns a bare JSON array/string/null for a method; a different JSON-RPC-ish service on the socket replies with non-envelope JSON (e.g. {"jsonrpc":"2.0",...} without ok, or plain [1,2,3]).
Common situations: Pointing the client at a non-cmux JSON service on the same path/port; daemon regression emitting envelopes without ok for some methods; protocol version skew after an upgrade.
Related errors
- Invalid cmux socket response: missing ok flag
- Replacement text is not valid UTF-8: {err}
- Missing or invalid field "${field}" in catalog: ${filePath}
- Marketplace catalog at ${filePath} must be a JSON object
- rpc frame must be an object
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6299142cba1b372b.
Report an issue: GitHub.