paperclipai/paperclip · error · Error
an immutable README asset ref is required
Error message
an immutable README asset ref is required
What it means
prepareNpmReadme() rewrites doc asset links in the README to point at an immutable git ref (commit SHA or tag) on raw.githubusercontent.com, so the npm-published README never references moving resources like 'main'. It refuses to run without an explicit assetRef because publishing relative/mutable links would break asset rendering on npm.
Solutions
- Pass an immutable ref (commit SHA or release tag) as the third CLI argument or second function argument, e.g. node scripts/prepare-npm-readme.mjs README.md dist/README.md abc1234.
- In the release script, resolve the ref with git rev-parse HEAD (or the tag) and fail early if empty before invoking prepareNpmReadme.
- If running programmatically, guard the call: if (!assetRef) throw before calling, to get a clearer stack at the call site.
Example fix
// before
prepareNpmReadme(readme, process.env.GIT_REF ?? "")
// after
const ref = execSync("git rev-parse HEAD").toString().trim();
if (!ref) throw new Error("cannot resolve immutable asset ref");
prepareNpmReadme(readme, ref) Defensive patterns
Strategy: try-catch
Validate before calling
const ref = process.argv[2];
if (!ref || ref.trim() === '') throw new Error('prepareNpmReadme: pass an immutable commit SHA or tag as assetRef'); Type guard
const isImmutableRef = (r) => typeof r === 'string' && /^[0-9a-f]{40}$|^(v?\d+\.\d+\.\d+)$/.test(r.trim()); Try / catch
try { const out = prepareNpmReadme(readme, ref); } catch (e) { if (e.message.includes('immutable README asset ref')) { console.error('Resolve the release SHA/tag first: git rev-parse HEAD'); process.exit(1); } throw e; } Prevention
- Resolve the ref from git (git rev-parse HEAD) in the release script, never from free-form env vars.
- Fail the release pipeline early if the ref resolves to an empty string.
- Prefer full commit SHAs or release tags over branch names for asset pinning.
When it happens
Trigger: Calling prepareNpmReadme(readme, assetRef) with assetRef === "" / undefined / null — e.g. the CLI wrapper invoked with only two arguments, or a release script computing the ref from an empty git describe output.
Common situations: A release pipeline step that forgets to pass the commit SHA/tag; a git command that resolves to an empty string (detached HEAD quirks, shallow clone without tags) feeding an empty ref into the script; manually running the module from another script without the third argument.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- A sandbox command is required.
- ACPX runtime executable package version mismatch: expected…
- ACPX runtime omitted its verified platform executable…
- ACPX provider package manifest could not be located for
- ACPX provider package name is invalid
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/b51612fc96ece811.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/prepare-npm-readme.mjs:7
import { readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
export function prepareNpmReadme(readme, assetRef) {
if (!assetRef) {
throw new Error("an immutable README asset ref is required");
}
const assetBaseUrl =
`https://raw.githubusercontent.com/paperclipai/paperclip/${assetRef}/doc/assets/`;
return readme.replace(
/((?:src|srcset)=["'])([^"']*)(["'])/g,
(_match, prefix, value, suffix) =>
`${prefix}${value.replace(
/(^|,\s*)doc\/assets\//g,
`$1${assetBaseUrl}`,
)}${suffix}`,
);
}
const isDirectRun =
process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
View on GitHub (pinned to 3f1d897a7c)