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

  1. Read the stderr tail embedded in the message — the core's own fatal line (config parse error, migration failure, panic) names the real cause
  2. Reproduce outside the harness with the same env: `OPENHUMAN_WORKSPACE=<workspace> ./target/debug/openhuman-core serve` to see the full startup error
  3. If the workspace is stale/corrupt, rerun with `--isolated-workspace --spawn-core` so the audit builds a fresh temp workspace
  4. Rebuild the binary: `cargo build --manifest-path Cargo.toml --bin openhuman-core`
  5. 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

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


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