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 expected revision comes from --expected-revision or from local git HEAD via execFileSync('git', ['rev-parse', 'HEAD']). It must match /^[0-9a-f]{40}$/i — a full 40-character commit SHA — because it is compared against the deployed build's sourceRevision. Short SHAs, tags, branch names, or a null from a missing/unusable git repo all fail with this message.
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 8880682c63)
Solutions
- Expand to the full SHA: `git rev-parse <short>` and pass the 40-char result
- If omitting the flag, run from a healthy repo checkout with git on PATH
- In CI, pass the exact commit — --expected-revision "$GITHUB_SHA" is already 40 chars
Example fix
# before --expected-revision v1.2.3 # after --expected-revision $(git rev-parse HEAD)
Defensive patterns
Strategy: validation
Validate before calling
const SHA_RE = /^[0-9a-f]{40}$/i;
const revision = args.expectedRevision || (await localRevision());
if (!SHA_RE.test(String(revision || ''))) {
console.error('expected revision must be an exact 40-character Git SHA');
process.exit(2);
} Type guard
function isFullGitSha(value) {
return /^[0-9a-f]{40}$/i.test(String(value || ''));
} Try / catch
try {
await main();
} catch (error) {
if (/exact 40-character Git SHA/.test(error.message)) { console.error('Pass --expected-revision $(git rev-parse HEAD)'); process.exit(2); }
throw error;
} Prevention
- Expand short SHAs with `git rev-parse` before passing them
- In CI, feed the exact commit SHA the workflow checked out (e.g. $GITHUB_SHA)
When it happens
Trigger: Passing --expected-revision with a short SHA (abc1234) or a tag (v1.2.3); omitting the flag outside a git checkout, in a shallow or broken repo, or where git is not installed.
Common situations: Pasting the abbreviated SHA GitHub displays; running the script from an exported tarball; a minimal container without git.
Related errors
- unknown argument: ${arg}
- invalid --base-url: ${args.baseUrl}
- --base-url must use http or https
- Invalid GitHub repository: ${repo}
- Invalid release tag: ${tag}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/5ff3cdead0a9e534.
Report an issue: GitHub.