paperclipai/paperclip · error · Error
A full lowercase source SHA is required.
Error message
A full lowercase source SHA is required.
What it means
assertSha in cloud-source-verification.mjs enforces that the commit SHA is a full 40-character lowercase hex string (a complete git SHA-1). Anything else — short SHAs, uppercase, 'HEAD', branch names — throws. All downstream GitHub API queries filter by head_sha and require the exact full SHA.
Solutions
- Expand the SHA: `git rev-parse <short-sha>` and pass the full 40-char lowercase result.
- In CI use the full github.sha context value.
- If the input is user-supplied, normalize to lowercase and validate /^[a-f0-9]{40}$/ before calling.
Example fix
// before
const sha = "a1b2c3d"; // short SHA
// after
const sha = require("node:child_process").execSync("git rev-parse a1b2c3d").toString().trim(); // full 40-char SHA Defensive patterns
Strategy: validation
Validate before calling
const FULL_SHA = /^[a-f0-9]{40}$/;
function resolveFullSha(input) {
const sha = String(input ?? "").trim().toLowerCase();
if (!FULL_SHA.test(sha)) throw new Error(`Provide a full 40-char lowercase SHA, got: ${input}`);
return sha;
} Type guard
const isFullSha = (v) => typeof v === "string" && /^[a-f0-9]{40}$/.test(v); Try / catch
try {
await waitForSourceVerification(sha, { api });
} catch (error) {
if (/full lowercase source SHA/.test(error.message)) {
console.error("Run: git rev-parse HEAD # and pass the full SHA.");
process.exitCode = 2;
} else throw error;
} Prevention
- Always expand short SHAs with git rev-parse before use
- In CI prefer the full github.sha context
- Add the SHA regex check at the entrypoint of your release script
When it happens
Trigger: Passing a short SHA (`abc1234`), an uppercase SHA, a branch/tag name, or an empty/undefined argv[2] to readSourceVerification, waitForSourceVerification, or the CLI `node scripts/cloud-source-verification.mjs <sha>`.
Common situations: Copy-pasting an abbreviated SHA from `git log --oneline`; CI providing github.sha as uppercase in some contexts; forgetting the CLI argument entirely; using `git rev-parse --short HEAD` output.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid project repositories directory
- Invalid project repository directory
- Project repository is not a Git checkout
- A reusable lease cannot be replaced and reacquired in the…
- A reusable lease handoff requires an execution workspace…
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/ac35120e73888010.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/cloud-source-verification.mjs:9
import { appendFile } from "node:fs/promises";
import { pathToFileURL } from "node:url";
const repository = "paperclipai/paperclip";
const workflowPath = ".github/workflows/cloud-readiness.yml";
export const sourceVerificationJob = "Cloud source verified v1";
function assertSha(sha) {
if (!/^[a-f0-9]{40}$/.test(sha ?? "")) throw new Error("A full lowercase source SHA is required.");
}
function trustedRun(run, sha, workflowId) {
return run.workflow_id === workflowId && run.path === workflowPath &&
run.repository?.full_name === repository && run.head_repository?.full_name === repository &&
run.head_sha === sha && run.head_branch === "master" && run.event === "push" &&
Number.isSafeInteger(run.id) && run.id > 0 &&
Number.isSafeInteger(run.run_attempt) && run.run_attempt > 0;
}
// Consume one versioned job, independent of image/migrator availability. A
// failed image build must not invalidate source checks that already passed.
export async function readSourceVerification(sha, api) {
assertSha(sha);
const workflow = await api(`/repos/${repository}/actions/workflows/cloud-readiness.yml`);
if (workflow.path !== workflowPath || !Number.isSafeInteger(workflow.id) || workflow.id < 1) {
throw new Error("Cloud readiness workflow identity does not match.");
}View on GitHub (pinned to 3f1d897a7c)