{"record":{"id":"44708bd7acb4a4cf","repo":"can1357/oh-my-pi","slug":"timed-out-initializing-daemon-broker-token-in-ru","errorCode":null,"errorMessage":"Timed out initializing daemon broker token in ${runtimeDir}","messagePattern":"Timed out initializing daemon broker token in (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/launch/client.ts","lineNumber":93,"sourceCode":"\t\t} catch (error) {\n\t\t\tif (!isEnoent(error)) throw error;\n\t\t}\n\n\t\ttry {\n\t\t\tconst handle = await fs.open(tokenPath, \"wx\", 0o600);\n\t\t\ttry {\n\t\t\t\tconst token = crypto.randomUUID().replaceAll(\"-\", \"\") + crypto.randomUUID().replaceAll(\"-\", \"\");\n\t\t\t\tawait handle.writeFile(token, \"utf8\");\n\t\t\t\treturn token;\n\t\t\t} finally {\n\t\t\t\tawait handle.close();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (!isEexist(error)) throw error;\n\t\t}\n\t\tawait Bun.sleep(10);\n\t}\n\tthrow new Error(`Timed out initializing daemon broker token in ${runtimeDir}`);\n}\n\nfunction requestTimeoutMs(operation: DaemonOperation): number {\n\tswitch (operation.op) {\n\t\tcase \"start\":\n\t\t\treturn (operation.spec.ready?.timeoutMs ?? CONNECT_TIMEOUT_MS) + 5_000;\n\t\tcase \"wait\":\n\t\tcase \"logs\":\n\t\tcase \"stop\":\n\t\t\treturn operation.timeoutMs + 5_000;\n\t\tdefault:\n\t\t\treturn 30_000;\n\t}\n}\n\nfunction openSocket(endpoint: string, timeoutMs: number): Promise<net.Socket> {\n\tconst { promise, resolve, reject } = Promise.withResolvers<net.Socket>();\n\tconst socket = net.createConnection({ path: endpoint });","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/launch/client.ts#L75-L111","documentation":"readOrCreateToken polls for the token file to appear in the runtime dir (handling EEXIST from concurrent creation), sleeping 10ms between attempts. If the token file never becomes readable before the loop budget is exhausted, it gives up with this timeout error.","triggerScenarios":"Calling DaemonBrokerClient.token()/readOrCreateToken while the broker process never creates the token file (broker failed to start, wrong runtimeDir, broker crashed before writing the token).","commonSituations":"Broker died at startup (e.g. missing env vars — see 'Daemon broker environment is incomplete'); pointing at a runtime dir owned by a dead broker; extremely slow filesystem; permissions preventing token creation.","solutions":["Confirm the broker process is alive and was started with correct DAEMON_RUNTIME_DIR_ENV","Check the runtime dir path is correct and writable; remove stale dirs so a fresh broker initializes","Investigate the broker's own startup error — this timeout is usually downstream of the broker crashing"],"exampleFix":"// before\nconst token = await client.token(); // throws on timeout\n// after\nlet token: string;\ntry { token = await client.token(); }\ncatch (err) { await startBroker(runtimeDir); token = await client.token(); }","handlingStrategy":"retry","validationCode":"if (!runtimeDir || !(await fs.stat(runtimeDir).catch(() => null))) throw new Error('runtimeDir does not exist: ' + runtimeDir);","typeGuard":null,"tryCatchPattern":"try {\n  const token = await client.token();\n} catch (err) {\n  if (err.message.startsWith('Timed out initializing daemon broker token')) {\n    await startBroker(runtimeDir); // broker likely never started\n    const token = await client.token();\n  } else throw err;\n}","preventionTips":["Ensure the broker process is running before awaiting token()","Remove stale runtime dirs pointing at dead brokers","Log broker stdout/stderr so its startup failures surface before this timeout"],"tags":["timeout","ipc","daemon","filesystem"],"backgroundTag":"token-init-timeout","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}