{"record":{"id":"8074ce89f25cff39","repo":"tinyhumansai/openhuman","slug":"spawned-core-exited-with-child-exitcode-stder-8074ce","errorCode":null,"errorMessage":"spawned core exited with ${child.exitCode}\n${stderrFn()}","messagePattern":"spawned core exited with (.+?)\n(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/debug/harness-cache-audit.mjs","lineNumber":538,"sourceCode":"  child.kill(\"SIGTERM\");\n  const exited = await Promise.race([\n    once(child, \"exit\").then(() => true),\n    new Promise((resolve) => setTimeout(() => resolve(false), 5_000)),\n  ]);\n  if (exited || child.exitCode !== null || child.signalCode !== null) return;\n\n  child.kill(\"SIGKILL\");\n  await Promise.race([\n    once(child, \"exit\"),\n    new Promise((resolve) => setTimeout(resolve, 2_000)),\n  ]);\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();","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/a221052e0df5b1f7598fceba7329fd1af95d6699/scripts/debug/harness-cache-audit.mjs#L520-L556","documentation":"Thrown by waitForCore() in the harness-cache-audit debug runner after it spawns the openhuman-core binary. Every 750ms poll first checks child.exitCode; if the child process has already terminated, the audit aborts immediately with the process exit code plus the tail of its captured stderr (last ~8000 chars). It means the core crashed or bailed during startup instead of ever becoming ready to answer core.ping on its /rpc endpoint.","triggerScenarios":"Running `node scripts/debug/harness-cache-audit.mjs --spawn-core` (or the pnpm debug wrapper) where the spawned core exits early: unreadable/invalid config.toml in the resolved workspace, a failed workspace migration at boot, a Rust panic during service init, a port conflict on the picked free port, or a stale target/debug/openhuman-core binary built from a different commit than the workspace data expects.","commonSituations":"Hand-edited or schema-outdated workspace config after pulling new core code; running against a workspace that another core instance already holds locked; cargo build artifacts from a mixed checkout; required env (OPENHUMAN_CORE_TOKEN etc.) not set so the core rejects startup.","solutions":["Read the stderr tail embedded in the message — the core's own fatal line (config parse error, migration failure, panic) names the real cause","Reproduce outside the harness with the same env: `OPENHUMAN_WORKSPACE=<workspace> ./target/debug/openhuman-core serve` to see the full startup error","If the workspace is stale/corrupt, rerun with `--isolated-workspace --spawn-core` so the audit builds a fresh temp workspace","Rebuild the binary: `cargo build --manifest-path Cargo.toml --bin openhuman-core`","Check nothing else is listening on the chosen port and no second core owns the workspace lock"],"exampleFix":"# before (crashing loop against a stale workspace)\nnode scripts/debug/harness-cache-audit.mjs --workspace ~/.openhuman/users/me/workspace\n\n# after (fresh isolated workspace, spawned core)\nnode scripts/debug/harness-cache-audit.mjs --isolated-workspace --spawn-core --keep-workspace","handlingStrategy":"try-catch","validationCode":"// before spawning: binary exists and is fresh\nimport { accessSync, constants } from \"node:fs\";\nconst BIN = \"target/debug/openhuman-core\";\ntry { accessSync(BIN, constants.X_OK); } catch {\n  console.error(\"core binary missing — run cargo build --bin openhuman-core\");\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const spawned = await spawnCore(opts);\n} catch (err) {\n  // err.message already carries child.exitCode + stderr tail\n  console.error(`core died at startup: ${err.message}`);\n  if (tempWorkspace) await rm(tempWorkspace, { recursive: true, force: true });\n  process.exitCode = 1;\n}","preventionTips":["Rebuild openhuman-core after pulling core changes before running spawn-based audits","Prefer --isolated-workspace for audits so workspace state cannot poison startup","Never point two spawn runs at the same workspace concurrently"],"tags":["process","startup","core","debug-runner","cli"],"backgroundTag":null,"analyzedSha":"a221052e0df5b1f7598fceba7329fd1af95d6699","analyzedAt":"2026-08-16T12:47:06.542Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}