tinyhumansai/openhuman · error · Error
spawned core exited with ${child.exitCode} ${stderrFn()}
Error message
spawned core exited with ${child.exitCode}
${stderrFn()} What it means
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.
Source
Thrown at scripts/debug/harness-cache-audit.mjs:538
child.kill("SIGTERM");
const exited = await Promise.race([
once(child, "exit").then(() => true),
new Promise((resolve) => setTimeout(() => resolve(false), 5_000)),
]);
if (exited || child.exitCode !== null || child.signalCode !== null) return;
child.kill("SIGKILL");
await Promise.race([
once(child, "exit"),
new Promise((resolve) => setTimeout(resolve, 2_000)),
]);
}
async function waitForCore(coreUrl, token, child, stderrFn) {
const deadline = Date.now() + 120_000;
while (Date.now() < deadline) {
if (child.exitCode !== null) {
throw new Error(
`spawned core exited with ${child.exitCode}\n${stderrFn()}`,
);
}
try {
await rpc(coreUrl, token, "core.ping", {}, 10_000);
return;
} catch {
await new Promise((resolve) => setTimeout(resolve, 750));
}
}
throw new Error(
`timed out waiting for spawned core at ${coreUrl}\n${stderrFn()}`,
);
}
async function main() {
const opts = parseArgs(process.argv.slice(2));
if (!opts.workspace) opts.workspace = await defaultWorkspace();View on GitHub (pinned to a221052e0d)
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
Example fix
# before (crashing loop against a stale workspace) node scripts/debug/harness-cache-audit.mjs --workspace ~/.openhuman/users/me/workspace # after (fresh isolated workspace, spawned core) node scripts/debug/harness-cache-audit.mjs --isolated-workspace --spawn-core --keep-workspace
Defensive patterns
Strategy: try-catch
Validate before calling
// before spawning: binary exists and is fresh
import { accessSync, constants } from "node:fs";
const BIN = "target/debug/openhuman-core";
try { accessSync(BIN, constants.X_OK); } catch {
console.error("core binary missing — run cargo build --bin openhuman-core");
process.exit(1);
} Try / catch
try {
const spawned = await spawnCore(opts);
} catch (err) {
// err.message already carries child.exitCode + stderr tail
console.error(`core died at startup: ${err.message}`);
if (tempWorkspace) await rm(tempWorkspace, { recursive: true, force: true });
process.exitCode = 1;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- timed out waiting for spawned core at ${coreUrl} ${stderrFn(
- spawned core exited with ${child.exitCode}\n${stderrFn()}
- timed out waiting for spawned core at ${coreUrl}\n${stderrFn
- OpenHuman could not reach its local runtime. Quit and reopen
- audio blob is empty
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/8074ce89f25cff39.
Report an issue: GitHub.