{"record":{"id":"c0477c76a77d1135","repo":"can1357/oh-my-pi","slug":"failed-to-connect-to-cmux-socket-at-this-socket","errorCode":null,"errorMessage":"Failed to connect to cmux socket at ${this.#socketPath}: ${err instanceof Error ? err.message : String(err)}","messagePattern":"Failed to connect to cmux socket at (.+?): (.+?)","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/browser/cmux/socket-client.ts","lineNumber":170,"sourceCode":"\t\tsocket.on(\"close\", () => this.#handleSocketClose());\n\n\t\ttry {\n\t\t\tawait this.#waitForConnect(socket);\n\t\t\tif (relayEndpoint && relayCredentials) {\n\t\t\t\tawait this.#authenticateRelay(relayEndpoint, relayCredentials);\n\t\t\t}\n\t\t\tif (this.#password) {\n\t\t\t\tconst line = await this.#sendLine(`auth ${this.#password}`, DEFAULT_CONNECT_TIMEOUT_MS);\n\t\t\t\tif (line.startsWith(\"ERROR:\") && !line.includes(\"Unknown command 'auth'\")) {\n\t\t\t\t\tthrow new ToolError(line);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.#connected = true;\n\t\t} catch (err) {\n\t\t\tthis.#connected = false;\n\t\t\tsocket.destroy();\n\t\t\tif (err instanceof ToolError) throw err;\n\t\t\tthrow new ToolError(\n\t\t\t\t`Failed to connect to cmux socket at ${this.#socketPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t#parseRelayEndpoint(): RelayEndpoint | null {\n\t\tconst value = this.#socketPath.trim();\n\t\tif (value.length === 0 || value.startsWith(\"/\")) {\n\t\t\treturn null;\n\t\t}\n\t\tconst match = /^(127\\.0\\.0\\.1|localhost):([0-9]+)$/.exec(value);\n\t\tif (!match) {\n\t\t\treturn null;\n\t\t}\n\t\tconst port = Number.parseInt(match[2] ?? \"\", 10);\n\t\tif (!Number.isInteger(port) || port < 1 || port > 65_535) {\n\t\t\treturn null;\n\t\t}","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/browser/cmux/socket-client.ts#L152-L188","documentation":"This is the catch-all wrapper in #openSocket: any failure during socket establishment, relay authentication, or password auth that is not already a ToolError is rethrown as `Failed to connect to cmux socket at <path>: <cause>`. It preserves the original error message (e.g. ECONNREFUSED, ENOENT, EACCES, timeout) while normalizing the type to ToolError.","triggerScenarios":"Unix socket file does not exist (ENOENT), no process listening (ECONNREFUSED), permission denied on the socket (EACCES), TCP connect timeout to a relay host:port, or a non-ToolError thrown inside the connect sequence.","commonSituations":"cmux daemon not running or crashed; wrong CMUX_SOCKET_PATH; stale socket file after an unclean daemon exit; firewall/host unreachable for 127.0.0.1:<port> relay endpoints; 10-second DEFAULT_CONNECT_TIMEOUT_MS exceeded on a slow relay.","solutions":["Confirm the cmux daemon is running and the socket path (CMUX_SOCKET_PATH) is correct and current","Remove a stale socket file and restart the daemon if the path exists but nothing listens","Check permissions on the socket file / relay port, and inspect the appended cause message (ECONNREFUSED/ENOENT/EACCES/timed out) to target the fix"],"exampleFix":"// before\nCMUX_SOCKET_PATH=/tmp/cmux/old-session.sock\n// after (regenerated by the live daemon)\nexport CMUX_SOCKET_PATH=$(cmux socket-path)","handlingStrategy":"retry","validationCode":"import { existsSync } from 'node:fs';\nconst socketPath = process.env.CMUX_SOCKET_PATH;\nif (!socketPath) throw new Error('CMUX_SOCKET_PATH not set');\nif (socketPath.startsWith('/') && !existsSync(socketPath)) {\n  throw new Error(`socket file missing: ${socketPath} — is the cmux daemon running?`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await client.connect();\n} catch (err) {\n  if (err instanceof ToolError && err.message.startsWith('Failed to connect to cmux socket')) {\n    if (err.message.includes('timed out')) { /* retry with backoff or check relay reachability */ }\n    if (err.message.includes('ENOENT') || err.message.includes('ECONNREFUSED')) { /* start the daemon / fix socket path */ }\n  }\n  throw err;\n}","preventionTips":["Health-check the socket/relay endpoint before first use (existsSync for unix paths)","Read the embedded cause (ENOENT/ECONNREFUSED/EACCES/timed out) to pick the fix","Regenerate CMUX_SOCKET_PATH after daemon restarts — never hardcode it","Add bounded retry with backoff for transient relay unavailability"],"tags":["network","socket","connection"],"backgroundTag":"connection-refused","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}