{"record":{"id":"8843e82b44c59dbe","repo":"Hmbown/CodeWhale","slug":"invalid-github-repository-repo","errorCode":null,"errorMessage":"Invalid GitHub repository: ${repo}","messagePattern":"Invalid GitHub repository: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/release/ensure-release-assets-absent.js","lineNumber":11,"sourceCode":"#!/usr/bin/env node\n\nconst { execFileSync } = require(\"node:child_process\");\n\nfunction usage() {\n  return \"Usage: node scripts/release/ensure-release-assets-absent.js OWNER/REPO vX.Y.Z\";\n}\n\nfunction validateTarget(repo, tag) {\n  if (!/^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/.test(repo)) {\n    throw new Error(`Invalid GitHub repository: ${repo}`);\n  }\n  if (!/^v[0-9]+\\.[0-9]+\\.[0-9]+$/.test(tag)) {\n    throw new Error(`Invalid release tag: ${tag}`);\n  }\n}\n\nfunction isNotFoundError(error) {\n  return (\n    error &&\n    error.status !== 0 &&\n    /\\bHTTP 404\\b/.test(String(error.stderr || \"\"))\n  );\n}\n\nfunction fetchRelease(repo, tag, ghBin = process.env.GH_BIN || \"gh\", exec = execFileSync) {\n  validateTarget(repo, tag);\n  const endpoint = `repos/${repo}/releases/tags/${encodeURIComponent(tag)}`;\n  let output;","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/release/ensure-release-assets-absent.js#L1-L29","documentation":"validateTarget() in scripts/release/ensure-release-assets-absent.js rejected the repository argument before any network call: it must match OWNER/REPO where each part contains only A-Z a-z 0-9 _ . and -. Spaces, URL forms, extra path segments, and .git suffixes all fail this strict shape check.","triggerScenarios":"Passing 'https://github.com/acme/codewhale', 'github.com/acme/codewhale.git', 'acme/codewhale/extra', an empty string, or any value with spaces/unicode as the first CLI argument.","commonSituations":"Copy-pasting from the browser URL bar; forwarding a repository env var that carries a prefix or .git; a template variable producing an empty owner in CI.","solutions":["Pass the bare slug exactly as OWNER/REPO, e.g. acme/codewhale — in GitHub Actions derive it from the GITHUB_REPOSITORY env var","If your source is a URL, strip the scheme, host, and .git suffix before invoking"],"exampleFix":"# before\nnode scripts/release/ensure-release-assets-absent.js https://github.com/acme/codewhale v1.2.3\n\n# after\nnode scripts/release/ensure-release-assets-absent.js acme/codewhale v1.2.3","handlingStrategy":"validation","validationCode":"function isValidGithubRepo(repo) {\n  return /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/.test(repo);\n}\n// before invoking:\nif (!isValidGithubRepo(repo)) throw new Error(`pass OWNER/REPO (got ${repo})`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In GitHub Actions use the GITHUB_REPOSITORY env var directly — it is already OWNER/REPO","Never forward URLs; strip scheme, host and .git before constructing the argument"],"tags":["cli","validation","github","release"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}