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

  1. If you don't need strict PEP 425 ordering checks, call `parse_wheel_filename(fn)` (default `validate_order=False`).
  2. Rebuild the wheel with a current backend that emits sorted tag runs.
  3. Re-sort the tag runs in the filename (split on `.`, sort each component, rejoin) and rename.
  4. 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

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


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/46546ce6e755dffe.json. Report an issue: GitHub.