nodejs/node · error · InvalidWheelFilename

Invalid wheel filename (invalid version): {filename}

Error message

Invalid wheel filename (invalid version): {filename}

What it means

InvalidWheelFilename raised when the version segment (parts[1]) of the wheel filename fails to parse as a PEP 440 Version. The inner InvalidVersion is chained via 'from e'. The version field is mandatory in PEP 427 and must be a valid PEP 440 version.

Source

Thrown at tools/gyp/pylib/packaging/utils.py:128

    filename = filename[:-4]
    dashes = filename.count("-")
    if dashes not in (4, 5):
        raise InvalidWheelFilename(
            f"Invalid wheel filename (wrong number of parts): {filename}"
        )

    parts = filename.split("-", dashes - 2)
    name_part = parts[0]
    # See PEP 427 for the rules on escaping the project name.
    if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:
        raise InvalidWheelFilename(f"Invalid project name: {filename}")
    name = canonicalize_name(name_part)

    try:
        version = Version(parts[1])
    except InvalidVersion as e:
        raise InvalidWheelFilename(
            f"Invalid wheel filename (invalid version): {filename}"
        ) from e

    if dashes == 5:
        build_part = parts[2]
        build_match = _build_tag_regex.match(build_part)
        if build_match is None:
            raise InvalidWheelFilename(
                f"Invalid build number: {build_part} in '{filename}'"
            )
        build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
    else:
        build = ()
    tags = parse_tag(parts[-1])
    return (name, version, build, tags)


def parse_sdist_filename(filename: str) -> Tuple[NormalizedName, Version]:

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Ensure the package version is a valid PEP 440 string (e.g. '1.0.0', '1.0.0a1', '1.0.0+local').
  2. Let the build backend derive the version rather than hardcoding an ad-hoc string.
  3. Inspect the chained InvalidVersion __cause__ for the precise PEP 440 violation.

Example fix

# before
# 'mypkg-1.0.BUILD7-py3-none-any.whl'

# after
# 'mypkg-1.0.0+build7-py3-none-any.whl'
Defensive patterns

Strategy: validation

Validate before calling

from packaging.version import Version, InvalidVersion
def wheel_version_is_valid(filename: str) -> bool:
    ver_part = filename[:-4].split('-')[1]
    try:
        Version(ver_part)
        return True
    except InvalidVersion:
        return False

Try / catch

try:
    parse_wheel_filename(fn)
except InvalidWheelFilename as e:
    cause = e.__cause__  # InvalidVersion with details
    # fix version in project metadata, rebuild

Prevention

When it happens

Trigger: A wheel whose version field is a non-PEP-440 string such as 'latest', '1.0.0-build.7' with disallowed syntax, or a date format not expressible in PEP 440.

Common situations: Custom version schemes that do not conform to PEP 440, or filenames where the version field was accidentally truncated/reordered during manual renaming.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/901eaa0c6db66724. Report an issue: GitHub.