tinyhumansai/openhuman · error · Error
Could not resolve latest GitHub Release tag for ${repo}
Error message
Could not resolve latest GitHub Release tag for ${repo} What it means
Thrown by resolveStartRef() when --from latest-release (the default) is used: it runs `gh release view --repo <repo> --json tagName --jq .tagName` to find the previous release tag that bounds the commit range. runGh uses execFileSync, so a hard gh failure (no releases at all) throws its own exec error with gh's stderr; this specific error fires when gh exits 0 but the resolved tag string is empty, leaving the script without a start ref.
Source
Thrown at scripts/release/generate-release-notes.mjs:152
if (to !== 'latest-tag') {
return to;
}
const tag = runGit(['describe', '--tags', '--abbrev=0']);
if (!tag) {
throw new Error('Could not resolve latest tag');
}
return tag;
}
function resolveStartRef(repo, from) {
if (from !== 'latest-release') {
return from;
}
const tag = runGh(['release', 'view', '--repo', repo, '--json', 'tagName', '--jq', '.tagName']);
if (!tag) {
throw new Error(`Could not resolve latest GitHub Release tag for ${repo}`);
}
return tag;
}
function assertRefExists(ref, label) {
try {
runGit(['rev-parse', '--verify', `${ref}^{commit}`], { allowFailure: true });
} catch {
throw new Error(`${label} ref not found: ${ref}`);
}
}
export function extractPullRequestNumbers(subject) {
const matches = [...String(subject || '').matchAll(/\(#(\d+)\)/g)];
return [...new Set(matches.map((match) => Number(match[1])).filter(Number.isInteger))];
}
export function parseGitLog(logText) {View on GitHub (pinned to a221052e0d)
Solutions
- Pass an explicit start ref instead: --from <previous-tag> (e.g. --from v0.57.18) — this is also what the script's own usage examples do for first cuts
- Check what gh actually returns: gh release view --repo <owner/repo> --json tagName --jq .tagName — an error or empty output reproduces the script's view
- Verify repo resolution: the script prefers --repo then GITHUB_REPOSITORY then the upstream/origin remotes; make sure they agree
- If the latest release is still a draft, publish it (gh release edit <tag> --draft=false) so latest-release can resolve it
Example fix
# before node scripts/release/generate-release-notes.mjs --from latest-release # first release, nothing to resolve # after — pin the start ref explicitly node scripts/release/generate-release-notes.mjs --from v0.57.18 --to main
Defensive patterns
Strategy: validation
Validate before calling
# preflight before invoking the script tag=$(gh release view --repo "$REPO" --json tagName --jq '.tagName' 2>/dev/null) if [ -z "$tag" ]; then echo "no published release on $REPO — pass --from <ref> explicitly" >&2 exit 1 fi node scripts/release/generate-release-notes.mjs --repo "$REPO" --from latest-release
Try / catch
if ! node scripts/release/generate-release-notes.mjs --from latest-release; then
echo 'latest-release unresolvable; retrying with pinned tag' >&2
node scripts/release/generate-release-notes.mjs --from "${LAST_KNOWN_TAG:?set LAST_KNOWN_TAG}"
fi Prevention
- publish the release before relying on --from latest-release
- pin --from to an explicit tag in CI for reproducible ranges
- add a gh release view preflight step to the release workflow
When it happens
Trigger: Running generate-release-notes.mjs with --from latest-release where the latest GitHub Release has no tagName resolvable by the jq filter, or where gh succeeds but prints empty output (edge states like a release whose tag object is missing). The practical neighborhood: first-ever release cut on a repo (no Release object), only-draft releases (gh release view then fails non-zero, producing the execFileSync error instead), or --repo/GITHUB_REPOSITORY pointing at a repo whose releases are not visible to the authenticated gh.
Common situations: Cutting the first release of a new repository; GITHUB_REPOSITORY env leaking a different slug in CI; gh authenticated to an org without release read scope; transferred/renamed repos where the old slug still resolves but shows no releases.
Related errors
- OPENAI_API_KEY is required unless --no-ai or --dry-run is us
- Invalid ${paramName}: '${value}'. Must be a valid integer ID
- Invalid ${paramName}: ${String(value)}. Type must be an inte
- RPC envelope contains undefined data
- RPC ${method} returned non-JSON HTTP ${res.status}: ${text.s
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/1ddcac4a94dd42cc.
Report an issue: GitHub.