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
- Inspect the package's wheels and confirm none carries a tag your interpreter emits (run packaging.tags.sys_tags() to see them).
- Add a wheel matching your platform/python to the package entry, or add an sdist as a fallback.
- Pass a broader tags= argument (or omit it to use sys_tags()) so a compatible wheel can be selected.
- 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
- Always include an sdist per package as a universal fallback.
- Generate locks on each target platform so a matching wheel exists.
- Pass tags=None to let select() use the running interpreter's sys_tags().
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
- Invalid wheel filename (compressed tag set components must…
- Invalid wheel filename (invalid tag component)
- Invalid wheel filename
- Multiple packages with the name
- Name in is not consistent with package name
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)