Hmbown/CodeWhale · error · Error
Invalid release tag: ${tag}
Error message
Invalid release tag: ${tag} What it means
validateTarget() rejected the tag argument: it must match ^v[0-9]+\.[0-9]+\.[0-9]+$ — a literal 'v' followed by exactly three non-negative integer components. Notably, prerelease and build suffixes are intentionally rejected: '1.2.3' (no v), 'v1.2', 'v1.2.3-rc.1', and 'v1.2.3+build' all fail. The check runs before gh is invoked.
Source
Thrown at scripts/release/ensure-release-assets-absent.js:14
#!/usr/bin/env node
const { execFileSync } = require("node:child_process");
function usage() {
return "Usage: node scripts/release/ensure-release-assets-absent.js OWNER/REPO vX.Y.Z";
}
function validateTarget(repo, tag) {
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repo)) {
throw new Error(`Invalid GitHub repository: ${repo}`);
}
if (!/^v[0-9]+\.[0-9]+\.[0-9]+$/.test(tag)) {
throw new Error(`Invalid release tag: ${tag}`);
}
}
function isNotFoundError(error) {
return (
error &&
error.status !== 0 &&
/\bHTTP 404\b/.test(String(error.stderr || ""))
);
}
function fetchRelease(repo, tag, ghBin = process.env.GH_BIN || "gh", exec = execFileSync) {
validateTarget(repo, tag);
const endpoint = `repos/${repo}/releases/tags/${encodeURIComponent(tag)}`;
let output;
try {
output = exec(ghBin, ["api", endpoint], {
encoding: "utf8",View on GitHub (pinned to 8880682c63)
Solutions
- Use the exact git tag form vX.Y.Z (e.g. v1.2.3) — in CI take it from github.ref_name or the pushed tag
- For prereleases, either retag as a stable vX.Y.Z or deliberately widen the regex if your process supports pre-release asset guards
- When converting from a semver string, prefix with 'v' and strip any prerelease/build suffix
Example fix
# before node scripts/release/ensure-release-assets-absent.js acme/codewhale 1.2.3 # after node scripts/release/ensure-release-assets-absent.js acme/codewhale v1.2.3
Defensive patterns
Strategy: validation
Validate before calling
function isValidReleaseTag(tag) {
return /^v[0-9]+\.[0-9]+\.[0-9]+$/.test(tag);
}
// before invoking:
if (!isValidReleaseTag(tag)) throw new Error(`pass vX.Y.Z exactly (got ${tag}); prerelease suffixes are rejected`); Prevention
- Take the tag from github.ref_name on tag push events rather than deriving it from package.json
- Remember the guard is strict: no '1.2.3', no 'v1.2', no '-rc.1' / '+build' suffixes
- If prerelease tags must be supported, widen the regex deliberately in a reviewed change
When it happens
Trigger: Passing a semver string from package.json (no 'v' prefix); a two-component tag like v1.2; a prerelease tag v1.2.3-rc1; a tag with build metadata v1.2.3+meta.
Common situations: Deriving the tag from the package version instead of the pushed git tag; tagging a release candidate and pointing the guard at it; manual invocation typos.
Related errors
- Invalid GitHub repository: ${repo}
- ${label} contains an invalid checksum row: ${trimmed}
- ${label} contains duplicate checksum rows for ${name}
- ${label} does not match the authoritative inventory; missing
- Release asset directory must be flat; found: ${nonFiles.map(
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/969d4c369ea167c4.
Report an issue: GitHub.