pypa/pip · error · PylockValidationError
Invalid wheel filename {wheel.filename!r}
Error message
Invalid wheel filename {wheel.filename!r} What it means
Raised as PylockValidationError by Package._from_dict in packaging.pylock when parse_wheel_filename(wheel.filename) raises (e.g. InvalidWheelFilename). It wraps the underlying error and tags the context with 'wheels[{i}]' so the offending wheel is identifiable. The filename must match the PEP 427 wheel naming convention.
Source
Thrown at src/pip/_vendor/packaging/pylock.py:601
)
distributions = bool(package.sdist) + len(package.wheels or [])
direct_urls = (
bool(package.vcs) + bool(package.directory) + bool(package.archive)
)
if distributions > 0 and direct_urls > 0:
raise PylockValidationError(
"None of vcs, directory, archive must be set if sdist or wheels are set"
)
if distributions == 0 and direct_urls != 1:
raise PylockValidationError(
"Exactly one of vcs, directory, archive must be set "
"if sdist and wheels are not set"
)
for i, wheel in enumerate(package.wheels or []):
try:
(name, version, _, _) = parse_wheel_filename(wheel.filename)
except Exception as e:
raise PylockValidationError(
f"Invalid wheel filename {wheel.filename!r}",
context=f"wheels[{i}]",
) from e
if name != package.name:
raise PylockValidationError(
f"Name in {wheel.filename!r} is not consistent with "
f"package name {package.name!r}",
context=f"wheels[{i}]",
)
if package.version and version != package.version:
raise PylockValidationError(
f"Version in {wheel.filename!r} is not consistent with "
f"package version {str(package.version)!r}",
context=f"wheels[{i}]",
)
if package.sdist:
try:
name, version = parse_sdist_filename(package.sdist.filename)View on GitHub (pinned to d7d0d0a394)
Solutions
- Set the wheel name/path/url to a valid PEP 427 filename: {distribution}-{version}-{python}-{abi}-{platform}.whl.
- Regenerate the lockfile so the resolver records correct wheel filenames.
- If setting path/url, ensure the basename is the wheel filename.
- Catch the error and report the bad filename and wheel index (context).
Example fix
# before [[packages.wheels]] name = \"foo-1.0\" # after [[packages.wheels]] name = \"foo-1.0-py3-none-any.whl\"
Defensive patterns
Strategy: validation
Validate before calling
from packaging.utils import parse_wheel_filename
def is_valid_wheel_name(fname: str) -> bool:
try:
parse_wheel_filename(fname)
return True
except Exception:
return False Type guard
import re
from packaging.utils import parse_wheel_filename
def is_wheel_filename(s: str) -> bool:
if not isinstance(s, str) or not s.endswith('.whl'):
return False
try:
parse_wheel_filename(s)
return True
except Exception:
return False Try / catch
try:
PylockFile.from_dict(data)
except PylockValidationError as e:
if 'Invalid wheel filename' in str(e):
repair_wheel_name(e.context) Prevention
- Use full PEP 427 wheel filenames: {dist}-{version}-{py}-{abi}-{plat}.whl.
- Validate with parse_wheel_filename before persisting.
- Ensure path/url basenames are valid wheel filenames.
- Catch and surface e.context (wheel index).
When it happens
Trigger: A wheel entry whose name/path/url resolves to a non-wheel filename like 'pkg-1.0.tar.gz', a malformed wheel name 'pkg.whl' (missing tags), or a name with invalid characters. Constructed via the wheel validation loop in Package._from_dict.
Common situations: Lockfile pointing a wheel entry at an sdist filename; truncated wheel name; tooling that recorded the project name instead of the wheel filename; cross-platform path separators breaking the filename extraction.
Related errors
- Cannot determine wheel filename
- Name in {wheel.filename!r} is not consistent with package na
- path or url must be provided
- Cannot determine sdist filename
- None of vcs, directory, archive must be set if sdist or whee
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/867ef34025f41698.json.
Report an issue: GitHub.