nodejs/node · error · InvalidVersion
Invalid version: '{version}'
Error message
Invalid version: '{version}' What it means
packaging.version.InvalidVersion raised by Version.__init__ when the version string does not match the PEP 440 regex even after the library's lenient normalization search. This is the canonical 'not a valid version' error for the whole packaging library and underpins several wheel/sdist filename errors.
Source
Thrown at tools/gyp/pylib/packaging/version.py:200
_regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE)
_key: CmpKey
def __init__(self, version: str) -> None:
"""Initialize a Version object.
:param version:
The string representation of a version which will be parsed and normalized
before use.
:raises InvalidVersion:
If the ``version`` does not conform to PEP 440 in any way then this
exception will be raised.
"""
# Validate the version and parse it into pieces
match = self._regex.search(version)
if not match:
raise InvalidVersion(f"Invalid version: '{version}'")
# Store the parsed out pieces of the version
self._version = _Version(
epoch=int(match.group("epoch")) if match.group("epoch") else 0,
release=tuple(int(i) for i in match.group("release").split(".")),
pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")),
post=_parse_letter_version(
match.group("post_l"), match.group("post_n1") or match.group("post_n2")
),
dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")),
local=_parse_local_version(match.group("local")),
)
# Generate a key which will be used for sorting
self._key = _cmpkey(
self._version.epoch,
self._version.release,
self._version.pre,View on GitHub (pinned to 1b2de5e052)
Solutions
- Strip leading 'v' and normalize the version to PEP 440 before constructing Version.
- Use packaging.version.parse() which tolerates legacy versions instead of strict Version().
- Catch InvalidVersion at the input boundary and report the offending string.
Example fix
# before
v = Version(tag) # tag = 'v1.0'
# after
from packaging.version import parse
v = parse(tag.lstrip('v')) Defensive patterns
Strategy: validation
Validate before calling
from packaging.version import Version, InvalidVersion
def is_pep440(version: str) -> bool:
try:
Version(version)
return True
except InvalidVersion:
return False Type guard
from packaging.version import Version
def as_version(v):
try:
return Version(v)
except InvalidVersion:
return None Try / catch
from packaging.version import parse, Version, InvalidVersion
try:
v = Version(raw)
except InvalidVersion:
v = parse(raw) # tolerates legacy forms Prevention
- Normalize VCS tags (strip 'v' prefix) before constructing Version.
- Use packaging.version.parse() for tolerant parsing.
- Validate versions at the input boundary.
When it happens
Trigger: Constructing Version('v1.0'), Version('1..0'), Version('1.0-beta'), or other non-PEP-440 strings raises. The regex uses .search() so a valid substring embedded in junk may slip through, but fully non-conforming strings fail.
Common situations: Parsing VCS tags (e.g. 'v1.0'), SCM-generated versions, date-only versions, or versions from languages with looser schemes (e.g. SemVer-with-build that PEP 440 rejects).
Related errors
- Invalid specifier: '{spec}'
- Invalid wheel filename (invalid version): {filename}
- Invalid sdist filename (invalid version): {filename}
- invalid metadata
- unparsed
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/f35553890fad00fe.
Report an issue: GitHub.