{"record":{"id":"2724da8522523a83","repo":"can1357/oh-my-pi","slug":"socket-not-ready-after-timeoutms-ms","errorCode":null,"errorMessage":"Socket not ready after ${timeoutMs}ms","messagePattern":"Socket not ready after (.+?)ms","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/dap/client.ts","lineNumber":783,"sourceCode":"\t\tthrow error;\n\t}\n}\n\n/** Poll a condition until it returns true, or timeout/process exit. */\nasync function waitForCondition(\n\tcheck: () => boolean | Promise<boolean>,\n\ttimeoutMs: number,\n\tproc: { exitCode: number | null },\n): Promise<void> {\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (Date.now() < deadline) {\n\t\tif (await check()) return;\n\t\tif (proc.exitCode !== null) {\n\t\t\tthrow new Error(\"Adapter process exited before socket was ready\");\n\t\t}\n\t\tawait Bun.sleep(50);\n\t}\n\tthrow new Error(`Socket not ready after ${timeoutMs}ms`);\n}\n\n/** Connect once to a TCP DAP server. */\nasync function connectTcpSocket(host: string, port: number, onClose?: () => void): Promise<SocketTransport> {\n\tconst { promise, resolve, reject } = Promise.withResolvers<SocketTransport>();\n\tlet streamController: ReadableStreamDefaultController<Uint8Array>;\n\tlet opened = false;\n\tconst readable = new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tstreamController = controller;\n\t\t},\n\t});\n\n\tvoid Bun.connect({\n\t\thostname: host,\n\t\tport,\n\t\tsocket: {\n\t\t\topen(socket) {","sourceCodeStart":765,"sourceCodeEnd":801,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/dap/client.ts#L765-L801","documentation":"The readiness poll for a DAP adapter's endpoint timed out: the check() predicate never succeeded within timeoutMs even though the process did not exit. The client gives up rather than blocking forever on an adapter that never becomes reachable.","triggerScenarios":"Adapter process runs but never opens the awaited socket/port within timeoutMs; check() keeps failing while the deadline elapses (slow machine, wrong port file, adapter waiting on stdin handshake that never comes); timeoutMs configured too low for a heavy adapter startup.","commonSituations":"Cold-start of a large adapter (first-run compile, antivirus scanning) exceeding the default timeout; adapter launched but waiting for input before listening; misconfigured host/port so the probe polls the wrong endpoint; debugger startup delayed under heavy system load.","solutions":["Increase the connect/startup timeoutMs passed to DapClient.connect or the session launch call","Inspect adapter stdout/stderr to confirm it is actually starting and what it is waiting on","Fix host/port configuration so the readiness check probes the correct endpoint","Pre-warm or speed up adapter startup (fix AV exclusions, remove first-run compiles) if it is genuinely slow"],"exampleFix":"// before\nconst client = await DapClient.connect({ adapter, cwd, timeoutMs: 5000 });\n// after\nconst client = await DapClient.connect({ adapter, cwd, timeoutMs: 30_000 }); // slow cold start","handlingStrategy":"validation","validationCode":"if (adapter.slowStart) timeoutMs = Math.max(timeoutMs, 60_000);","typeGuard":null,"tryCatchPattern":"try {\n  await DapClient.connect({ adapter, cwd, timeoutMs });\n} catch (err) {\n  if (String((err as Error).message).startsWith('Socket not ready')) {\n    // retry once with a longer window before giving up\n    return await DapClient.connect({ adapter, cwd, timeoutMs: timeoutMs * 3 });\n  }\n  throw err;\n}","preventionTips":["Set startup timeouts generously (30s+) for heavyweight adapters","Watch adapter stdout for readiness lines ('listening at ...') to confirm it is starting","Fix host/port config so readiness probes hit the right endpoint","Pre-warm adapters or cache started instances to avoid repeated cold starts"],"tags":["dap","timeout","startup","debug-adapter"],"backgroundTag":"readiness-timeout","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}