can1357/oh-my-pi · error · ToolError
Failed to connect to cmux socket at ${this.#socketPath}: ${e
Error message
Failed to connect to cmux socket at ${this.#socketPath}: ${err instanceof Error ? err.message : String(err)} What it means
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.
Source
Thrown at packages/coding-agent/src/tools/browser/cmux/socket-client.ts:170
socket.on("close", () => this.#handleSocketClose());
try {
await this.#waitForConnect(socket);
if (relayEndpoint && relayCredentials) {
await this.#authenticateRelay(relayEndpoint, relayCredentials);
}
if (this.#password) {
const line = await this.#sendLine(`auth ${this.#password}`, DEFAULT_CONNECT_TIMEOUT_MS);
if (line.startsWith("ERROR:") && !line.includes("Unknown command 'auth'")) {
throw new ToolError(line);
}
}
this.#connected = true;
} catch (err) {
this.#connected = false;
socket.destroy();
if (err instanceof ToolError) throw err;
throw new ToolError(
`Failed to connect to cmux socket at ${this.#socketPath}: ${err instanceof Error ? err.message : String(err)}`,
);
}
}
#parseRelayEndpoint(): RelayEndpoint | null {
const value = this.#socketPath.trim();
if (value.length === 0 || value.startsWith("/")) {
return null;
}
const match = /^(127\.0\.0\.1|localhost):([0-9]+)$/.exec(value);
if (!match) {
return null;
}
const port = Number.parseInt(match[2] ?? "", 10);
if (!Number.isInteger(port) || port < 1 || port > 65_535) {
return null;
}View on GitHub (pinned to 9690622007)
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
Example fix
// before CMUX_SOCKET_PATH=/tmp/cmux/old-session.sock // after (regenerated by the live daemon) export CMUX_SOCKET_PATH=$(cmux socket-path)
Defensive patterns
Strategy: retry
Validate before calling
import { existsSync } from 'node:fs';
const socketPath = process.env.CMUX_SOCKET_PATH;
if (!socketPath) throw new Error('CMUX_SOCKET_PATH not set');
if (socketPath.startsWith('/') && !existsSync(socketPath)) {
throw new Error(`socket file missing: ${socketPath} — is the cmux daemon running?`);
} Try / catch
try {
await client.connect();
} catch (err) {
if (err instanceof ToolError && err.message.startsWith('Failed to connect to cmux socket')) {
if (err.message.includes('timed out')) { /* retry with backoff or check relay reachability */ }
if (err.message.includes('ENOENT') || err.message.includes('ECONNREFUSED')) { /* start the daemon / fix socket path */ }
}
throw err;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- AnthropicConnectionError
- Gemini Files API upload initialization request failed
- Gemini Files API upload finalization request failed
- Could not connect to OAuth server. Please check the URLs and
- Failed to start SSH master for ${target}${detail}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c0477c76a77d1135.
Report an issue: GitHub.