Hmbown/CodeWhale · error · Error

expected revision must be an exact 40-character Git SHA

Error message

expected revision must be an exact 40-character Git SHA

What it means

The script requires the expected source revision to be a full 40-character hexadecimal Git SHA. It takes --expected-revision if given, otherwise derives it from the local checkout via localRevision(); either way the value must match /^[0-9a-f]{40}$/i or the script aborts so it never compares against an ambiguous or wrong revision.

Solutions

  1. Resolve the full SHA with `git rev-parse HEAD` (or `git rev-parse <ref>^{commit}`) and pass that as --expected-revision
  2. Run the script from inside the git repository so localRevision() can produce a full SHA
  3. Remove any surrounding whitespace or quotes from the value

Example fix

// before
--expected-revision abc1234
// after
--expected-revision $(git rev-parse HEAD)
Defensive patterns

Strategy: validation

Validate before calling

if (!/^[0-9a-f]{40}$/i.test(revision)) throw new Error('need full 40-char SHA');

Type guard

const isFullSha = (v) => typeof v === 'string' && /^[0-9a-f]{40}$/i.test(v);

Try / catch

try { run(args); } catch (e) { if (e.message.includes('expected revision')) { console.error('Pass $(git rev-parse HEAD)'); process.exitCode = 2; } else throw e; }

Prevention

When it happens

Trigger: Passing --expected-revision with a short SHA (e.g. 7 chars), a branch/tag name like 'main', a value with whitespace, or running in a repo where localRevision() returns empty/malformed output.

Common situations: Copying a short SHA from `git log --oneline`, passing a tag name instead of a SHA, or running the script outside a git checkout so no revision can be resolved.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/5ff3cdead0a9e534. Report an issue: GitHub.

Appendix: source

Thrown at web/scripts/compare-deployed-facts.mjs:113

  }
  return differences;
}

async function main() {
  const args = parseArgs(process.argv.slice(2));
  let baseUrl;
  try {
    baseUrl = new URL(args.baseUrl);
  } catch {
    throw new Error(`invalid --base-url: ${args.baseUrl}`);
  }
  if (!/^https?:$/.test(baseUrl.protocol)) {
    throw new Error("--base-url must use http or https");
  }

  const expectedRevision = args.expectedRevision || localRevision();
  if (!expectedRevision || !/^[0-9a-f]{40}$/i.test(expectedRevision)) {
    throw new Error("expected revision must be an exact 40-character Git SHA");
  }
  if (!Number.isInteger(args.attempts) || args.attempts < 1 || args.attempts > 20) {
    throw new Error("--attempts must be an integer from 1 to 20");
  }
  if (!Number.isFinite(args.retryDelayMs) || args.retryDelayMs < 0 || args.retryDelayMs > 30_000) {
    throw new Error("--retry-delay-ms must be between 0 and 30000");
  }

  const facts = buildFacts();
  const expected = {
    sourceRevision: expectedRevision,
    version: facts.version,
    providerCount: facts.providers.length,
    toolCount: facts.toolCount,
    latestPublishedRelease: facts.latestPublishedRelease,
  };
  const endpoint = new URL("/api/facts", baseUrl).toString();
  let last = { error: "not attempted" };

View on GitHub (pinned to 433685b202)