{"record":{"id":"2020dd7eb63027cc","repo":"tinyhumansai/openhuman","slug":"timed-out-waiting-for-spawned-core-at-coreurl","errorCode":null,"errorMessage":"timed out waiting for spawned core at ${coreUrl}\n${stderrFn()}","messagePattern":"timed out waiting for spawned core at (.+?)\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/debug/harness-cache-audit.mjs","lineNumber":549,"sourceCode":"  ]);\n}\n\nasync function waitForCore(coreUrl, token, child, stderrFn) {\n  const deadline = Date.now() + 120_000;\n  while (Date.now() < deadline) {\n    if (child.exitCode !== null) {\n      throw new Error(\n        `spawned core exited with ${child.exitCode}\\n${stderrFn()}`,\n      );\n    }\n    try {\n      await rpc(coreUrl, token, \"core.ping\", {}, 10_000);\n      return;\n    } catch {\n      await new Promise((resolve) => setTimeout(resolve, 750));\n    }\n  }\n  throw new Error(\n    `timed out waiting for spawned core at ${coreUrl}\\n${stderrFn()}`,\n  );\n}\n\nasync function main() {\n  const opts = parseArgs(process.argv.slice(2));\n  if (!opts.workspace) opts.workspace = await defaultWorkspace();\n\n  let tempWorkspace = \"\";\n  let spawned;\n  if (opts.isolatedWorkspace) {\n    if (!opts.spawnCore)\n      throw new Error(\"--isolated-workspace requires --spawn-core\");\n    tempWorkspace = await mkdtemp(\n      path.join(tmpdir(), \"openhuman-harness-cache-audit-\"),\n    );\n    opts.workspace = path.join(tempWorkspace, \"workspace\");\n    await mkdir(opts.workspace, { recursive: true });","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/debug/harness-cache-audit.mjs#L531-L567","documentation":"Thrown by waitForCore() in harness-cache-audit when the 120-second readiness deadline expires. The child process is still alive (exitCode is null) but every attempt to POST core.ping to coreUrl has failed, so the script gives up and prints the endpoint plus the core's stderr tail. It means the core started but never answered on the expected /rpc URL within 120s.","triggerScenarios":"`--spawn-core` with a very slow boot (large workspace migration, cold model/store init taking >120s); a wrong --core-url when OPENHUMAN_CORE_RPC_URL was exported (coreUrlExplicit path skips the auto-picked port); a bearer token mismatch making ping return 401 forever (each rpc() throw is treated as not-ready); the chosen port stolen between pickFreePort() and core bind; core bound to a different interface than 127.0.0.1.","commonSituations":"First run against a huge existing workspace that needs a long migration; exporting OPENHUMAN_CORE_RPC_URL pointing at an old/dead port and combining it with --spawn-core; heavy CI machine where startup exceeds 2 minutes; token file from a previous core run no longer matching.","solutions":["Read the embedded stderr tail — a still-initializing core shows migration/store init progress; if it looks healthy, the URL/token is the problem","If OPENHUMAN_CORE_RPC_URL is exported, unset it (or pass an explicit matching --core-url) so --spawn-core auto-picks the port it actually binds","Verify the token the script uses matches the spawned core's token (with --spawn-core the script generates it; don't also pass --token)","Give the core a smaller/fresher workspace (--isolated-workspace) to shorten boot","Retry on a loaded machine — if boot genuinely needs >120s, run the core manually and attach without --spawn-core"],"exampleFix":"# before: exported stale URL overrides the spawned core's address\nexport OPENHUMAN_CORE_RPC_URL=http://127.0.0.1:8765/rpc\nnode scripts/debug/harness-cache-audit.mjs --spawn-core\n\n# after: let the harness pick the port for the core it spawns\nunset OPENHUMAN_CORE_RPC_URL\nnode scripts/debug/harness-cache-audit.mjs --spawn-core","handlingStrategy":"retry","validationCode":"// pre-flight the endpoint shape before entering the wait loop\nimport { request } from \"node:http\";\nconst pre = await fetch(coreUrl.replace(/\\/rpc$/, \"/health\"), { signal: AbortSignal.timeout(2000) }).catch(() => null);\nif (pre && pre.ok) console.log(\"core answering /health; /rpc readiness likely imminent\");","typeGuard":null,"tryCatchPattern":"for (let attempt = 1; attempt <= 2; attempt++) {\n  try { await runAudit(opts); break; }\n  catch (err) {\n    if (!/timed out waiting for spawned core/.test(String(err.message)) || attempt === 2) throw err;\n    await new Promise((r) => setTimeout(r, 5000)); // machine was loaded; retry once\n  }\n}","preventionTips":["Unset OPENHUMAN_CORE_RPC_URL when using --spawn-core so the auto-picked port is authoritative","Don't pass --token together with --spawn-core","Keep audited workspaces small or isolated to keep boot under the 120s window"],"tags":["startup","timeout","rpc","core","debug-runner"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}