can1357/oh-my-pi · error · Error

${command.join(" ")} exited with code ${exitCode}

Error message

${command.join(" ")} exited with code ${exitCode}

What it means

The `run` helper in tb/agent.ts spawns a command via Bun.spawn and throws this error when the process exits with a non-zero code. Stdout/stderr are inherited, so the actual failure output has already been printed; the error just records which command failed and its exit code.

Source

Thrown at packages/metaharness/src/tb/agent.ts:17

import * as fs from "node:fs/promises";
import * as path from "node:path";
import type { AgentBinaries, GatewayConfig, GuestArch } from "./types";
import type { TrialVm } from "./vmon";

const REPO_ROOT = path.resolve(import.meta.dir, "../../../..");
const CODING_AGENT_DIR = path.join(REPO_ROOT, "packages", "coding-agent");
const NATIVES_DIR = path.join(REPO_ROOT, "packages", "natives", "native");

function shellQuote(value: string): string {
	return `'${value.replaceAll("'", `'"'"'`)}'`;
}

async function run(command: string[], cwd?: string): Promise<void> {
	const process = Bun.spawn(command, { cwd, stdout: "inherit", stderr: "inherit" });
	const exitCode = await process.exited;
	if (exitCode !== 0) throw new Error(`${command.join(" ")} exited with code ${exitCode}`);
}
/**
 * Refresh cross-target `pi_natives.linux-<arch>*.node` files in
 * `packages/natives/native/` from the published npm leaf package.
 *
 * The binary build embeds whatever `.node` files sit in that directory; on a
 * non-linux host they are stale local cross-builds that can fail `dlopen`
 * inside task guests (undefined libstdc++ symbols). The matching published
 * leaf is the artifact real installs load, so it is the ground truth for
 * embedding; an unpublished working-tree version fails instead of risking
 * loader/API skew.
 */
async function refreshCrossNatives(arches: GuestArch[], version: string): Promise<void> {
	for (const arch of arches) {
		if (process.platform === "linux" && process.arch === arch) continue;
		const pkg = `pi-natives-linux-${arch}`;
		const response = await fetch(`https://registry.npmjs.org/@oh-my-pi/${pkg}/-/${pkg}-${version}.tgz`);
		if (!response.ok) throw new Error(`Fetching @oh-my-pi/${pkg}@${version} failed: HTTP ${response.status}`);

View on GitHub (pinned to 9690622007)

Solutions

  1. Inspect the inherited stdout/stderr above the error for the real failure cause
  2. Re-run the failing command manually to reproduce and debug
  3. Ensure required tools (bun, cargo/rust toolchain) are installed and on PATH
  4. Check the command's arguments and cwd are correct for your environment

Example fix

// before
await run(["bun", "scripts/ci-release-build-binaries.ts", "--targets", targets], REPO_ROOT);
// after — precondition check surfaced to the user
if (!$which("cargo")) throw new Error("cargo is required to build agent binaries");
await run(["bun", "scripts/ci-release-build-binaries.ts", "--targets", targets], REPO_ROOT);
Defensive patterns

Strategy: try-catch

Validate before calling

// verify prerequisites before spawning
if (!$which("cargo")) throw new Error("cargo not found: required for binary build");

Try / catch

try {
  await run(["bun", "scripts/ci-release-build-binaries.ts", "--targets", targets], REPO_ROOT);
} catch (err) {
  // stderr was inherited/printed; add context for the caller
  throw new Error(`binary build failed: ${err instanceof Error ? err.message : err}`);
}

Prevention

When it happens

Trigger: Any command run by `run()` (e.g. `bun scripts/ci-release-build-binaries.ts --targets ...` during prepareAgentBinaries, or other build/setup commands) exits non-zero.

Common situations: Binary build script fails due to missing toolchain, compilation errors, OOM, or missing deps; network fetches inside the script fail; wrong working directory passed to `run()`.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/975954c231fa9de3. Report an issue: GitHub.