pypa/pip · error · PylockSelectError

No wheel found matching the provided tags for package

Error message

No wheel found matching the provided tags for package {package.name!r} at packages[{package_index}], and no sdist available as a fallback

What it means

PylockSelectError raised by Pylock.select when a package has wheels but none matches the (provided or default) compatibility tags, and the package has no sdist to fall back to. PEP 751 wheel selection picks the best wheel via create_compatible_tags_selector; if that yields nothing and there is no sdist, there is no installable artifact.

Solutions

  1. Inspect the package's wheels and confirm none carries a tag your interpreter emits (run packaging.tags.sys_tags() to see them).
  2. Add a wheel matching your platform/python to the package entry, or add an sdist as a fallback.
  3. Pass a broader tags= argument (or omit it to use sys_tags()) so a compatible wheel can be selected.
  4. Regenerate the lock on the target platform so it includes a matching wheel or an sdist.

Example fix

# before: package only has windows wheel, selecting on linux
[[packages]]
name = "foo"
  [[packages.wheels]]
  filename = "foo-1.0-cp312-cp312-win_amd64.whl"

# after: add a manylinux wheel or an sdist fallback
[[packages]]
name = "foo"
  [[packages.wheels]]
  filename = "foo-1.0-cp312-cp312-manylinux_2_17_x86_64.whl"
  [packages.sdist]
  filename = "foo-1.0.tar.gz"
Defensive patterns

Strategy: validation

Validate before calling

from packaging.tags import sys_tags, create_compatible_tags_selector
from packaging.utils import parse_wheel_filename

def package_has_installable_artifact(package, tags=None) -> bool:
    if package.sdist is not None or package.vcs or package.directory or package.archive:
        return True
    selector = create_compatible_tags_selector(tags or sys_tags())
    for w in package.wheels or []:
        if selector([(w, parse_wheel_filename(w.filename)[-1])]) is not None:
            return True
    return False

for p in pylock.packages:
    assert package_has_installable_artifact(p), p.name

Type guard

null

Try / catch

from packaging.pylock import PylockSelectError
try:
    list(pylock.select(tags=tags))
except PylockSelectError as e:
    # add a matching wheel or an sdist; widen tags
    report(e)

Prevention

When it happens

Trigger: Calling pylock.select(tags=...) (or defaulting to sys_tags()) for a package whose wheels are all for other platforms/Python versions (e.g. only 'cp312-cp312-win_amd64' wheels while selecting on Linux CPython 3.11) and whose sdist is absent.

Common situations: A cross-platform lock without a wheel for your interpreter/platform; running on a different Python than the lock was built for; tags= passed explicitly that are too narrow.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/cc6101bd3fb4d054. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_vendor/packaging/pylock.py:929

            # - Else if there are entries for :ref:`pylock-packages-wheels`:
            elif package.wheels:
                # #. Look for the appropriate wheel file based on
                #    :ref:`pylock-packages-wheels-name`; if one is not found then move
                #    on to :ref:`pylock-packages-sdist` or an error MUST be raised about
                #    a lack of source for the project.
                best_wheel = next(
                    compatible_tags_selector(
                        (wheel, parse_wheel_filename(wheel.filename)[-1])
                        for wheel in package.wheels
                    ),
                    None,
                )
                if best_wheel:
                    yield package, best_wheel
                elif package.sdist is not None:
                    yield package, package.sdist
                else:
                    raise PylockSelectError(
                        f"No wheel found matching the provided tags "
                        f"for package {package.name!r} "
                        f"at packages[{package_index}], "
                        f"and no sdist available as a fallback"
                    )

            # - Else if no :ref:`pylock-packages-wheels` file is found or
            #   :ref:`pylock-packages-sdist` is solely set:
            elif package.sdist is not None:
                yield package, package.sdist

            else:
                # Covered by lock.validate() which is a precondition for this method.
                raise NotImplementedError  # pragma: no cover

View on GitHub (pinned to f399c37189)