headroomlabs-ai/headroom · error · ValueError
Invalid release tag: {tag}
Error message
Invalid release tag: {tag} What it means
Raised by parse_release_tag() when the tag does not match the release tag regex (X.Y.Z with an optional legacy fourth numeric component). This parser exists specifically to accept historic 4-part tags and record their ordering via legacy_height; strings outside that shape are rejected.
Source
Thrown at headroom/release_version.py:118
version: SemVer
legacy_height: int = -1
raw: str = ""
@dataclass(frozen=True)
class CommitInfo:
"""Commit subject/body pair used for bump detection."""
subject: str
body: str = ""
def parse_release_tag(tag: str) -> ReleaseTag:
"""Parse a release tag, preserving legacy fourth-component ordering."""
match = RELEASE_TAG_RE.match(tag)
if not match:
raise ValueError(f"Invalid release tag: {tag}")
major, minor, patch, extra = match.groups()
return ReleaseTag(
version=SemVer(int(major), int(minor), int(patch)),
legacy_height=int(extra) if extra is not None else -1,
raw=tag,
)
def normalize_release_tag(tag: str) -> SemVer:
"""Collapse historic 4-part release tags into their base semantic version."""
return parse_release_tag(tag).version
def find_latest_release_tag(tags: Sequence[str]) -> str | None:
"""Return the latest release tag after normalizing legacy 4-part tags."""
candidates: list[ReleaseTag] = []View on GitHub (pinned to 322425c43b)
Solutions
- Extract the numeric portion before parsing, e.g. strip a known prefix with a regex.
- Pass only actual release tags (X.Y.Z or X.Y.Z.N) to parse_release_tag().
- Normalize tags once in CI (e.g. ${GITHUB_REF_NAME#v}) before calling release tooling.
Example fix
# before
tag_info = parse_release_tag(github_ref) # 'v1.2.3'
# after
tag_info = parse_release_tag(github_ref.removeprefix('v')) Defensive patterns
Strategy: validation
Validate before calling
import re
RELEASE_TAG = re.compile(r'^\d+\.\d+\.\d+(?:\.\d+)?$')
if not RELEASE_TAG.match(tag):
raise ValueError(f'not a release tag: {tag!r}')
info = parse_release_tag(tag) Type guard
import re
def is_release_tag(tag: str) -> bool:
return re.match(r'^\d+\.\d+\.\d+(?:\.\d+)?$', tag) is not None Try / catch
try:
info = parse_release_tag(tag.removeprefix('v').strip())
except ValueError as e:
raise ReleaseError(f'bad tag {tag!r}: {e}') from e Prevention
- Normalize refs once in CI (strip prefixes, whitespace) before release tooling sees them.
- Only pass tag refs to parse_release_tag(), never branch names or describe output.
- Standardize tag format (optionally 'v'-prefixed) across the repository.
When it happens
Trigger: Calling parse_release_tag('v1.2.3'), parse_release_tag('release-1.2.3'), parse_release_tag('1.2'), or passing a branch/ref name instead of a tag.
Common situations: Repository tags carry a prefix ('v' or 'release-') while the parser expects bare numeric tags; sorting mixed refs; trailing whitespace or glob patterns from 'git describe' output.
Related errors
- Invalid semantic version: {value}
- Unsupported bump level: {level}
- invalid pipeline config TOML: {0}
- recommendations file not found: {0}
- bedrock_eventstream_parse_failed
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/3b78f17f9a9e89c9.
Report an issue: GitHub.