tinyhumansai/openhuman · error · Error

gh failed (${r.status}): ${r.stderr?.trim() || "unknown erro

Error message

gh failed (${r.status}): ${r.stderr?.trim() || "unknown error"}

What it means

fetchPrsFromGh() in scripts/agent-batch/status.mjs shells out to `gh pr list --repo <base_repo> --search label:batch:<batch_id> --json ...` via spawnSync and throws when the child exits non-zero, embedding gh's trimmed stderr. This is the single PR-discovery call the status table is built from, so any gh/CLI/auth/network failure surfaces here.

Source

Thrown at scripts/agent-batch/status.mjs:74

function fetchPrsFromGh(spec) {
  // One `gh pr list` call per batch — cheap and avoids N+1.
  const args = [
    "pr",
    "list",
    "--repo",
    spec.base_repo,
    "--state",
    "all",
    "--search",
    `label:batch:${spec.batch_id}`,
    "--json",
    "headRefName,number,url,state,statusCheckRollup",
    "--limit",
    "100",
  ];
  const r = spawnSync("gh", args, { encoding: "utf8" });
  if (r.status !== 0) {
    throw new Error(
      `gh failed (${r.status}): ${r.stderr?.trim() || "unknown error"}`,
    );
  }
  return JSON.parse(r.stdout || "[]");
}

function indexByBranch(prs) {
  const m = new Map();
  for (const pr of prs) {
    // `statusCheckRollup` from gh is an array of contexts when populated; we
    // only care about the worst-status rollup for the cell.
    let rollup = null;
    if (
      Array.isArray(pr.statusCheckRollup) &&
      pr.statusCheckRollup.length > 0
    ) {
      const states = pr.statusCheckRollup
        .map((c) => c.conclusion || c.state)

View on GitHub (pinned to a221052e0d)

Solutions

  1. Run `gh auth status` — if not logged in, `gh auth login` or export a valid GH_TOKEN/GITHUB_TOKEN
  2. Verify gh is on PATH (`command -v gh`); install it if missing — status null in the message means the binary was not found
  3. Check network/proxy reachability: `gh pr list --repo tinyhumansai/openhuman --limit 1` should succeed standalone
  4. Re-run the status command once transient network/rate-limit conditions clear (the message carries gh's own stderr for diagnosis)

Example fix

# before
$ node scripts/agent-batch/status.mjs batch.json
Error: gh failed (1): gh auth not logged in

# after
$ gh auth login
$ node scripts/agent-batch/status.mjs batch.json
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight before invoking status.mjs
import { spawnSync } from "node:child_process";
const auth = spawnSync("gh", ["auth", "status"], { encoding: "utf8" });
if (auth.status !== 0) throw new Error("gh not authenticated — run `gh auth login`");
const probe = spawnSync("gh", ["pr", "list", "--repo", "tinyhumansai/openhuman", "--limit", "1"], { encoding: "utf8" });
if (probe.status !== 0) throw new Error(`gh unreachable: ${probe.stderr}`);

Try / catch

function fetchPrsSafe(spec, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    const r = spawnSync("gh", prListArgs(spec), { encoding: "utf8" });
    if (r.status === 0) return JSON.parse(r.stdout || "[]");
    if (r.error || /rate limit|timed out|ECONNRESET/i.test(r.stderr || "")) {
      await sleep(5000 * (i + 1));
      continue;
    }
    throw new Error(`gh failed (${r.status}): ${r.stderr}`); // auth/repo errors are not transient
  }
  throw new Error("gh pr list kept failing after retries");
}

Prevention

When it happens

Trigger: Running `node scripts/agent-batch/status.mjs <spec.json>` (or --post) when: gh is not installed (spawnSync yields status null and the message reads 'gh failed (null): unknown error'), `gh auth status` shows no login, GH_TOKEN is expired/revoked, there is no network egress to api.github.com, or the repo tinyhumansai/openhuman is unreachable. Also fires on any gh CLI flag/API incompatibility after a gh version change.

Common situations: Running the batch tooling in a fresh container or CI runner without gh installed/authenticated; corporate proxies blocking api.github.com; a revoked PAT used via GH_TOKEN; gh major-version upgrades that change pr list flags. Note validateSpec() pins base_repo to tinyhumansai/openhuman, so a wrong-repo typo fails earlier with a SpecError, not here.

Related errors


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