{"record":{"id":"fec571f43f55cc91","repo":"can1357/oh-my-pi","slug":"failed-to-start-daemon-broker-lasterror-messag","errorCode":null,"errorMessage":"Failed to start daemon broker: ${lastError?.message ?? \"socket unavailable\"}","messagePattern":"Failed to start daemon broker: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/coding-agent/src/launch/client.ts","lineNumber":305,"sourceCode":"\t\t\tthis.#bindSocket(await openSocket(this.#endpoint, 250));\n\t\t\treturn;\n\t\t} catch {\n\t\t\t// No live broker. Multiple clients may race to spawn; the broker's PID\n\t\t\t// lease selects one winner before any candidate touches the socket.\n\t\t}\n\t\tthis.#spawnBroker();\n\t\tconst deadline = Date.now() + CONNECT_TIMEOUT_MS;\n\t\tlet lastError: Error | undefined;\n\t\twhile (Date.now() < deadline) {\n\t\t\ttry {\n\t\t\t\tthis.#bindSocket(await openSocket(this.#endpoint, 250));\n\t\t\t\treturn;\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tawait Bun.sleep(CONNECT_RETRY_MS);\n\t\t\t}\n\t\t}\n\t\tthrow new Error(`Failed to start daemon broker: ${lastError?.message ?? \"socket unavailable\"}`);\n\t}\n\n\t#spawnBroker(): void {\n\t\tconst spawn = resolveWorkerSpawnCmd(DAEMON_BROKER_WORKER_ARG);\n\t\tconst overlay: Record<string, string> = {\n\t\t\t[DAEMON_PROJECT_DIR_ENV]: this.projectDir,\n\t\t\t[DAEMON_RUNTIME_DIR_ENV]: this.#runtimeDir,\n\t\t};\n\t\tif (this.#idleGraceMs !== undefined) overlay[DAEMON_IDLE_GRACE_ENV] = String(this.#idleGraceMs);\n\t\tconst child = Bun.spawn(spawn.cmd, {\n\t\t\tcwd: spawn.cwd,\n\t\t\tenv: workerEnvFromParent(overlay),\n\t\t\tstdin: \"ignore\",\n\t\t\tstdout: \"ignore\",\n\t\t\tstderr: \"ignore\",\n\t\t\t...BROKER_SPAWN_OPTIONS,\n\t\t});\n\t\tchild.unref();","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/launch/client.ts#L287-L323","documentation":"#connectOnce attempts to connect to the broker socket and, if unreachable, spawns the broker and retries within a deadline. When all attempts fail, it throws this aggregate error carrying the last underlying failure's message (or 'socket unavailable' if none was captured).","triggerScenarios":"Broker repeatedly fails to start (bad env, missing worker entry, crash loop) or the socket path is unusable, exhausting the connect deadline.","commonSituations":"Runtime dir on a filesystem without unix socket support; broker worker crashing at startup (see env/token errors); permission issues on the socket file; port/path collisions between projects.","solutions":["Read lastError in the message — fix the underlying broker startup failure first","Verify the runtime dir is writable and the worker entry resolves (workerHostEntry / fallback)","Run the broker in the foreground to see its real startup error, then retry the client"],"exampleFix":"// before\nawait client.request(op); // throws aggregate start failure\n// after\ntry { await client.request(op); }\ncatch (err) {\n  logger.error(\"daemon broker start failed\", { cause: err.message }); // inspect lastError, fix root cause\n  throw err;\n}","handlingStrategy":"retry","validationCode":"const socketPath = daemonBrokerEndpoint(projectDir, runtimeDir);\nawait fs.mkdir(runtimeDir, { recursive: true });\nawait fs.access(runtimeDir, fs.constants.W_OK); // runtime dir must be writable before connecting","typeGuard":null,"tryCatchPattern":"try {\n  await client.request({ op: 'ping' });\n} catch (err) {\n  if (err.message.startsWith('Failed to start daemon broker')) {\n    logger.error('broker start failed', { cause: err.message }); // message embeds lastError — fix root cause\n  }\n  throw err;\n}","preventionTips":["Verify runtimeDir is on a filesystem supporting unix sockets (not some network mounts)","Ensure the worker host entry resolves before spawning","Run the broker manually once to observe its real startup error"],"tags":["ipc","startup","daemon","connection"],"backgroundTag":"daemon-start-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}