{"record":{"id":"8aa926099946c256","repo":"can1357/oh-my-pi","slug":"invalid-cmux-socket-response-missing-ok-flag","errorCode":null,"errorMessage":"Invalid cmux socket response: missing ok flag","messagePattern":"Invalid cmux socket response: missing ok flag","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/browser/cmux/socket-client.ts","lineNumber":403,"sourceCode":"\t\t\tthrow new ToolError(line);\n\t\t}\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = JSON.parse(line);\n\t\t} catch (err) {\n\t\t\tthrow new ToolError(`Invalid cmux socket JSON response: ${err instanceof Error ? err.message : String(err)}`);\n\t\t}\n\t\tif (!payload || typeof payload !== \"object\") {\n\t\t\tthrow new ToolError(\"Invalid cmux socket response: expected object\");\n\t\t}\n\t\tconst response = payload as { ok?: unknown; result?: unknown; error?: CmuxErrorPayload };\n\t\tif (response.ok === true) {\n\t\t\treturn (response.result ?? {}) as Record<string, unknown>;\n\t\t}\n\t\tif (response.ok === false) {\n\t\t\tthrow new ToolError(formatCmuxError(response.error));\n\t\t}\n\t\tthrow new ToolError(\"Invalid cmux socket response: missing ok flag\");\n\t}\n\n\t#handleSocketFailure(err: Error): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#connected = false;\n\t\tthis.#connectPromise = null;\n\t\tthis.#rejectAll(new ToolError(`cmux socket error: ${err.message}`));\n\t\tthis.#socket?.destroy();\n\t\tthis.#socket = null;\n\t}\n\n\t#handleSocketClose(): void {\n\t\tconst hadPendingRead = this.#lineWaiters.length > 0;\n\t\tthis.#connected = false;\n\t\tthis.#connectPromise = null;\n\t\tthis.#socket = null;\n\t\tif (!this.#disposed && hadPendingRead) {\n\t\t\tthis.#rejectAll(new ToolError(\"cmux socket closed\"));","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/browser/cmux/socket-client.ts#L385-L421","documentation":"A parsed object reply that contains neither ok === true nor ok === false has no verdict flag, so #parseResponse throws this ToolError. It is the last-resort envelope validation: the peer produced a JSON object but not a cmux response object.","triggerScenarios":"Daemon (or another JSON service on the socket) returns objects like {\"jsonrpc\":\"2.0\",\"id\":...} or event/notification objects lacking ok; protocol skew where newer daemons emit a different envelope for some methods.","commonSituations":"Mixing client and daemon versions; connecting to a different JSON-over-line service that happens to emit objects; daemon bug emitting notification frames interleaved into request replies.","solutions":["Align client and daemon versions so the {ok,...} envelope contract holds on both ends","Verify the socketPath targets the cmux control socket, not an event/notification stream","Capture the offending raw line in daemon logs and fix or report the envelope regression"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function hasOkFlag(v: unknown): v is { ok: boolean } {\n  return typeof v === \"object\" && v !== null && \"ok\" in v && typeof (v as { ok: unknown }).ok === \"boolean\";\n}","tryCatchPattern":"try {\n  return await client.request(method, params);\n} catch (err) {\n  if (err instanceof ToolError && err.message === \"Invalid cmux socket response: missing ok flag\") {\n    // envelope/protocol mismatch: align versions or check you're on the control socket\n  }\n  throw err;\n}","preventionTips":["Keep client and daemon on the same protocol version — envelopes without ok come from version skew","Ensure the socketPath is the request/response control socket, not an event stream","Log raw lines during integration testing to catch envelope regressions early"],"tags":["json","schema","protocol"],"backgroundTag":"response-schema-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}