nodejs/node · error · InvalidWheelFilename
Invalid wheel filename (extension must be '.whl'): {filename
Error message
Invalid wheel filename (extension must be '.whl'): {filename} What it means
packaging.utils.InvalidWheelFilename raised by parse_wheel_filename when the filename does not end with '.whl'. This is the first sanity check before PEP 427 structural parsing; any other extension (or none) is rejected immediately.
Source
Thrown at tools/gyp/pylib/packaging/utils.py:107
if parsed.post is not None:
parts.append(f".post{parsed.post}")
# Development release
if parsed.dev is not None:
parts.append(f".dev{parsed.dev}")
# Local version segment
if parsed.local is not None:
parts.append(f"+{parsed.local}")
return "".join(parts)
def parse_wheel_filename(
filename: str,
) -> Tuple[NormalizedName, Version, BuildTag, FrozenSet[Tag]]:
if not filename.endswith(".whl"):
raise InvalidWheelFilename(
f"Invalid wheel filename (extension must be '.whl'): {filename}"
)
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:View on GitHub (pinned to 1b2de5e052)
Solutions
- Branch on extension before parsing: use parse_sdist_filename for .tar.gz/.zip and parse_wheel_filename for .whl.
- Verify the filename ends with '.whl' (e.g. Path(filename).suffix == '.whl') before calling.
- Catch InvalidWheelFilename and skip or log non-wheel entries when iterating a list of mixed filenames.
Example fix
# before
name, ver, build, tags = parse_wheel_filename(fname)
# after
if fname.endswith('.whl'):
name, ver, build, tags = parse_wheel_filename(fname)
elif fname.endswith(('.tar.gz', '.zip')):
name, ver = parse_sdist_filename(fname)
else:
raise ValueError(f'Unknown distribution type: {fname}') Defensive patterns
Strategy: type-guard
Validate before calling
def is_wheel(filename: str) -> bool:
return filename.endswith('.whl') Type guard
from pathlib import Path
def is_wheel_path(p) -> bool:
return Path(p).suffix == '.whl' Try / catch
try:
parsed = parse_wheel_filename(filename)
except InvalidWheelFilename:
pass # route to sdist parser or skip Prevention
- Branch on suffix before choosing wheel vs sdist parser.
- Filter directory listings by extension before batch parsing.
- Use pathlib.Path.suffix for robust extension checks.
When it happens
Trigger: Calling parse_wheel_filename('foo-1.0.tar.gz'), parse_wheel_filename('foo-1.0-py3-none-any.zip'), or any string lacking the .whl suffix.
Common situations: Routing sdist and wheel filenames through the same parser, or passing a URL/path whose extension was stripped or altered.
Related errors
- Invalid wheel filename (wrong number of parts): {filename}
- Invalid project name: {filename}
- Invalid wheel filename (invalid version): {filename}
- Invalid build number: {build_part} in '{filename}'
- Invalid sdist filename (extension must be '.tar.gz' or '.zip
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/0428dc15126c64c3.
Report an issue: GitHub.