JuliusBrussee/caveman · error · Error

failed

Error message

${operation} failed: ${detail}

What it means

check-profile-scope's requireGit helper wraps every git invocation; if the git process errors, exits non-zero, or cannot be spawned, it throws Error(`${operation} failed: ${detail}`) embedding git's stderr (or the spawn error). It is a generic wrapper meaning 'a git subcommand this script ran did not succeed', not a domain error — the real cause is always in the detail string.

Solutions

  1. Read the detail suffix of the message — it contains git's stderr; fix that underlying cause first
  2. Install git / ensure it is on PATH in the execution environment
  3. Run the script from inside the repository (or pass the correct cwd option)
  4. Fetch the missing base revision if a shallow clone lacks it (git fetch origin <base>)
  5. Run the failing git command manually with the same args to reproduce

Example fix

// before: run in non-repo dir
checkProfileScope({ base, head })
// after
checkProfileScope({ base, head, cwd: '/path/to/repo' })
Defensive patterns

Strategy: try-catch

Validate before calling

import { execFileSync } from 'node:child_process';
function gitAvailable(cwd) {
  try { execFileSync('git', ['rev-parse', '--is-inside-work-tree'], { cwd, stdio: 'pipe' }); return true; }
  catch { return false; }
}
if (!gitAvailable(cwd)) throw new Error(`not a git repo / git missing at ${cwd}`);

Try / catch

try { checkProfileScope({ base, head, cwd }); } catch (e) {
  if (/failed:/.test(e.message)) {
    console.error('git invocation failed:', e.message); // detail carries git stderr
    process.exitCode = 1;
  } else throw e;
}

Prevention

When it happens

Trigger: git not installed or not on PATH (spawn error), running the script outside a git repository or wrong cwd, a bad revision passed to cat-file/diff, or any git command exiting non-zero (e.g. corrupted repo, permission issues).

Common situations: CI container without git, running the profile-scope check before repo initialization, shallow clones missing the base commit, or a typo'd base/head ref.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/01ffd729710647bd. Report an issue: GitHub.

Appendix: source

Thrown at agents/check-profile-scope.mjs:33

]);
const SCHEMA_SUPPORT_PATHS = new Set([
  SCHEMA_PATH,
  "agents/compile.mjs",
  "agents/check-profile-scope.mjs",
  "packages/cli/tests/agent-registry.runtime.mjs",
  "tests/installer/agent-registry-compile.test.mjs",
  "tests/installer/agent-registry-scope.test.mjs",
  ...GENERATED_PATHS,
]);

function runGit(cwd, args, encoding = "utf8") {
  return spawnSync("git", args, { cwd, encoding, maxBuffer: 8 * 1024 * 1024 });
}

function requireGit(result, operation) {
  if (!result.error && result.status === 0) return result.stdout;
  const detail = result.stderr?.toString().trim() || result.error?.message || `exit ${result.status}`;
  throw new Error(`${operation} failed: ${detail}`);
}

function isConcreteProfile(path) {
  return path !== SCHEMA_PATH && /^agents\/profiles\/[a-z0-9][a-z0-9-]*\.json$/.test(path);
}

function isAllowedConcreteProfileCommitPath(path) {
  return isConcreteProfile(path) || GENERATED_PATHS.has(path);
}

export function checkProfileScope({ base, head, cwd = process.cwd() }) {
  if (!REVISION_RE.test(base) || !REVISION_RE.test(head)) {
    throw new Error("base and head must be full Git object IDs");
  }

  const baseRegistry = runGit(cwd, ["cat-file", "-e", `${base}:agents/agents.json`]);
  if (baseRegistry.error || baseRegistry.status !== 0) {
    return { ok: true, skipped: true, message: "profile registry absent at base (initial import); skipping lane-scope gate" };

View on GitHub (pinned to 3ee70a1026)