paperclipai/paperclip · error · Error
Invalid GitHub ref '${options.ref}'.
Error message
Invalid GitHub ref '${options.ref}'. What it means
Sanity guard on the --ref flag: the value is URL-encoded into a GitHub API path, so a ref that is not a plausible branch/tag/commit identifier is rejected up front rather than producing a confusing 404 from the API.
Source
Thrown at cli/src/commands/install.ts:136
}
export async function resolvePublishedVersion(spec: string, runCommand: CommandRunner): Promise<string> {
const result = await runCommand(
"npm",
["view", `paperclipai@${spec}`, "version", "--json", `--registry=${PUBLIC_NPM_REGISTRY}`],
{ maxBuffer: 1024 * 1024 },
);
return parseResolvedVersion(result.stdout);
}
export function resolveGitInstallRequest(options: InstallOptions): { repo: string; ref: string; pinned: boolean } | null {
if (!options.ref && !options.repo) return null;
if (!options.ref) throw new Error("--repo requires --ref.");
if (options.canary || options.version) throw new Error("--ref cannot be combined with --canary or --version.");
const repo = (options.repo ?? DEFAULT_GITHUB_REPO).trim();
const ref = options.ref.trim();
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repo)) throw new Error(`--repo must be an owner/name GitHub repository, received '${repo}'.`);
if (!ref || ref.startsWith("-") || /[\0\r\n]/.test(ref)) throw new Error(`Invalid GitHub ref '${options.ref}'.`);
return { repo, ref, pinned: /^[0-9a-f]{7,40}$/i.test(ref) };
}
async function runGitHubCurl(
args: string[],
runCommand: CommandRunner,
options?: Parameters<CommandRunner>[2],
): Promise<{ stdout: string; stderr: string }> {
// Anonymous GitHub requests are rate-limited per source IP (CI runners and
// corporate NAT exhaust the shared quota); honor an ambient token when present.
// The token travels via a curl --config file so it never appears in process args.
const token = process.env.GH_TOKEN ?? process.env.GITHUB_TOKEN;
if (!token) return runCommand("curl", args, options);
const configDir = fs.mkdtempSync(path.join(os.tmpdir(), "paperclipai-gh-"));
const configFile = path.join(configDir, "headers");
try {
fs.writeFileSync(configFile, `header = "Authorization: Bearer ${token}"\n`, { mode: 0o600 });
return await runCommand("curl", ["--config", configFile, ...args], options);View on GitHub (pinned to 01ad858492)
Solutions
- Pass a valid git ref (branch, tag, or commit SHA) to --ref.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at cli/src/commands/install.ts:136 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-08-18).
Data as JSON: /api/errors/90bbb485fa649c97.
Report an issue: GitHub.