tinyhumansai/openhuman · error · Error
timed out waiting for spawned core at ${coreUrl}\n${stderrFn
Error message
timed out waiting for spawned core at ${coreUrl}\n${stderrFn()} What it means
waitForCore() in scripts/debug/agent-prepare-context-audit.mjs gives the spawned core 180 seconds (750ms ping interval, 10s per core.ping attempt) to answer; if the deadline passes with the child still alive but core.ping never succeeding, it throws 'timed out waiting for spawned core at <url>' plus the stderr tail. Unlike error 217, the core did NOT exit — it just never became RPC-ready in time.
Source
Thrown at scripts/debug/agent-prepare-context-audit.mjs:627
await waitForCore(opts.coreUrl, token, child, () => stderr);
return { child, token };
}
async function waitForCore(coreUrl, token, child, stderrFn) {
const deadline = Date.now() + 180_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((r) => setTimeout(r, 750));
}
}
throw new Error(
`timed out waiting for spawned core at ${coreUrl}\n${stderrFn()}`,
);
}
async function stopChild(child) {
if (child.exitCode !== null || child.signalCode !== null) return;
child.kill("SIGTERM");
const exited = await Promise.race([
once(child, "exit").then(() => true),
new Promise((r) => setTimeout(() => r(false), 5_000)),
]);
if (exited || child.exitCode !== null || child.signalCode !== null) return;
child.kill("SIGKILL");
await Promise.race([
once(child, "exit"),
new Promise((r) => setTimeout(r, 2_000)),
]);
}View on GitHub (pinned to a221052e0d)
Solutions
- Pre-build, then re-run: cargo build --manifest-path Cargo.toml --bin openhuman-core — with a warm target, cargo run starts the binary almost immediately and the 180s budget is plenty
- Run once with --verbose to stream the core's stdout/stderr and see whether it is compiling, booting, or stuck
- Verify the port in --core-url matches what the core logs as its listen port (startCore passes OPENHUMAN_CORE_PORT derived from that URL — keep them consistent)
- If boot itself is slow (migrations, first-run setup), let one run complete to warm the workspace, then subsequent runs start fast
Example fix
# before $ node scripts/debug/agent-prepare-context-audit.mjs --spawn-core Error: timed out waiting for spawned core at http://127.0.0.1:7788/rpc # after (warm the build cache first so cargo run skips compilation) $ cargo build --manifest-path Cargo.toml --bin openhuman-core $ node scripts/debug/agent-prepare-context-audit.mjs --spawn-core
Defensive patterns
Strategy: retry
Validate before calling
// Make the wait unnecessary: verify a warm binary exists before spawning
import { existsSync } from "node:fs";
const bin = "target/debug/openhuman-core";
if (!existsSync(bin)) {
console.error("cold target — building first so the 180s startup wait isn't spent compiling");
spawnSync("cargo", ["build", "--manifest-path", "Cargo.toml", "--bin", "openhuman-core"], { stdio: "inherit" });
} Try / catch
try {
await waitForCore(coreUrl, token, child, () => stderr);
} catch (e) {
if (/timed out waiting for spawned core/.test(e.message)) {
// child still alive = probably still compiling; check target/ freshness and try once more
if (stillCompiling()) { console.error("build was cold — binary now warm, retrying"); await waitForCore(coreUrl, token, child, () => stderr); }
else throw e;
} else throw e;
} Prevention
- The 180s window includes the cargo build — pre-warm target/ with cargo build before every --spawn-core session
- Derive the port only from --core-url (as startCore does) so the polled URL and the bound port can never disagree
- First run in a fresh workspace is the slowest (migrations/setup); let one run complete to warm it before tuning timeouts
When it happens
Trigger: --spawn-core with a cold cargo target directory: `cargo run` compiles the openhuman-core binary first, and a cold build of this large crate routinely exceeds 180s, so the wait times out while rustc is still running. Also: the core binding a different port than the URL polled, first-boot workspace migrations/model setup being slow, or the core starting but the ping being rejected (auth mismatch between the injected OPENHUMAN_CORE_TOKEN and what the core expects).
Common situations: First --spawn-core run after a clean clone or cargo clean; running right after a branch switch that invalidates the build cache; a slower CI box or laptop where compile plus boot overshoots 3 minutes; the child stuck on a network fetch during boot (never exits, never serves).
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- spawned core exited with ${child.exitCode}\n${stderrFn()}
- timed out waiting for core at ${coreUrl} ${stderrFn()}
- Invalid ${paramName}: '${value}'. Must be a valid integer ID
- spawned core exited with ${child.exitCode} ${stderrFn()}
- spawned core exited with ${child.exitCode} ${stderrFn()}
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/cfcef46f49491349.
Report an issue: GitHub.