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

  1. 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
  2. Run once with --verbose to stream the core's stdout/stderr and see whether it is compiling, booting, or stuck
  3. 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)
  4. 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

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

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/cfcef46f49491349. Report an issue: GitHub.