pypa/pip · warning · InvalidWheelFilename
Invalid wheel filename (compressed tag set components must b
Error message
Invalid wheel filename (compressed tag set components must be in sorted order per PEP 425): {filename!r} What it means
Raised by `parse_wheel_filename` when `parse_tag(tag_str, validate_order=True)` raises `UnsortedTagsError`, meaning the compressed tag set (the `py-abi-platform` portion, which may use `.` to combine tags) is not in sorted order per PEP 425. The wheel spec requires each tag-set component (interpreter, abi, platform runs separated by `.`) to be sorted ascending; reordering is a strictly informational validation controlled by the `validate_order` parameter (added in 26.1).
Source
Thrown at src/pip/_vendor/packaging/utils.py:242
raise InvalidWheelFilename(
f"Invalid wheel filename (invalid version): {filename!r}"
) 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!r}"
)
build = cast("BuildTag", (int(build_match.group(1)), build_match.group(2)))
else:
build = ()
tag_str = parts[-1]
try:
tags = parse_tag(tag_str, validate_order=validate_order)
except UnsortedTagsError:
raise InvalidWheelFilename(
f"Invalid wheel filename (compressed tag set components must be in "
f"sorted order per PEP 425): {filename!r}"
) from None
return (name, version, build, tags)
def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
"""
This function takes the filename of a sdist file (as specified
in the `Source distribution format`_ documentation), and parses
it, returning a tuple of the normalized name and version as
represented by an instance of :class:`~packaging.version.Version`.
:param str filename: The name of the sdist file.
:raises InvalidSdistFilename: If the filename does not end
with an sdist extension (``.zip`` or ``.tar.gz``), or if it does not
contain a dash separating the name and the version of the distribution.
View on GitHub (pinned to d7d0d0a394)
Solutions
- If you don't need strict PEP 425 ordering checks, call `parse_wheel_filename(fn)` (default `validate_order=False`).
- Rebuild the wheel with a current backend that emits sorted tag runs.
- Re-sort the tag runs in the filename (split on `.`, sort each component, rejoin) and rename.
- Report the non-compliant wheel to its publisher.
Example fix
// before parse_wheel_filename(fn, validate_order=True) # raises on unsorted tags # after parse_wheel_filename(fn) # validate_order defaults to False
Defensive patterns
Strategy: validation
Validate before calling
def will_pass_order_check(filename: str) -> bool:
# The error only fires when validate_order=True; default is safe.
return True # call parse_wheel_filename(fn) without validate_order=True Try / catch
from pip._vendor.packaging.utils import parse_wheel_filename, InvalidWheelFilename
try:
parse_wheel_filename(filename, validate_order=True)
except InvalidWheelFilename as e:
if 'sorted order' in str(e):
# relax the check or rebuild with sorted tag runs
parse_wheel_filename(filename) # validate_order=False
else:
raise Prevention
- Only enable `validate_order=True` when you specifically need PEP 425 strictness.
- Rebuild wheels with a backend that emits sorted compressed tag sets.
- Treat ordering issues as warnings, not hard failures, unless compliance gating requires it.
When it happens
Trigger: Calling `parse_wheel_filename(fn, validate_order=True)` on a filename whose tag run is unsorted, e.g. `...-py3-none-any` is fine but a multi-tag run like `cp311.cp310-...` out of order, or an ABI/platform run not sorted. With the default `validate_order=False` this is never raised.
Common situations: Enabling strict ordering validation; a wheel produced by a tool that didn't sort the compressed tag sets; verifying PEP 425 compliance in a linter/CI gate.
Related errors
- Tag component {component!r} is not in sorted order per PEP 4
- name is invalid: {name!r}
- Invalid wheel filename (extension must be '.whl'): {filename
- Invalid wheel filename (wrong number of parts): {filename!r}
- Invalid project name: {filename!r}
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/46546ce6e755dffe.json.
Report an issue: GitHub.