pypa/pip · error · UnknownExtra
%s has no such extra feature %r
Error message
%s has no such extra feature %r
What it means
Raised as UnknownExtra (a ResolutionError subclass) from Distribution.requires() when an extras name passed in is not present in the distribution's dependency map. The message formats the distribution and the offending extra so you can see which package was queried and which extra it does not declare.
Source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:3077
return dm
def _build_dep_map(self):
dm = {}
for name in 'requires.txt', 'depends.txt':
for extra, reqs in split_sections(self._get_metadata(name)):
dm.setdefault(extra, []).extend(parse_requirements(reqs))
return dm
def requires(self, extras: Iterable[str] = ()):
"""List of Requirements needed for this distro if `extras` are used"""
dm = self._dep_map
deps: list[Requirement] = []
deps.extend(dm.get(None, ()))
for ext in extras:
try:
deps.extend(dm[safe_extra(ext)])
except KeyError as e:
raise UnknownExtra(
"%s has no such extra feature %r" % (self, ext)
) from e
return deps
def _get_metadata_path_for_display(self, name):
"""
Return the path to the given metadata file, if available.
"""
try:
# We need to access _get_metadata_path() on the provider object
# directly rather than through this class's __getattr__()
# since _get_metadata_path() is marked private.
path = self._provider._get_metadata_path(name)
# Handle exceptions e.g. in case the distribution's metadata
# provider doesn't support _get_metadata_path().
except Exception:
return '[could not detect]'View on GitHub (pinned to d7d0d0a394)
Solutions
- Check the distribution's metadata (pip show <pkg>, or its METADATA 'Provides-Extra' lines) for the exact extra names it supports.
- Correct the extra name spelling/casing in your call to requires().
- Upgrade or downgrade the package to a version that declares the extra you need.
Example fix
# before
dist.requires(['tsets']) # typo -> UnknownExtra
# after
extra = 'tests' if 'tests' in dist.extras else None
if extra:
dist.requires([extra]) Defensive patterns
Strategy: validation
Validate before calling
extras = [e for e in requested_extras if e in dist.extras]
missing = set(requested_extras) - set(extras)
if missing:
raise ValueError(f'extras not provided by {dist}: {missing}')
dist.requires(extras) Type guard
def extra_is_provided(dist, extra: str) -> bool:
return extra in getattr(dist, 'extras', set()) Try / catch
try:
dist.requires([extra])
except pkg_resources.UnknownExtra as e:
# log and continue without that extra
... Prevention
- Read dist.extras before calling requires().
- Derive extra names from the package's METADATA 'Provides-Extra' rather than guessing.
When it happens
Trigger: Calling dist.requires(['some_extra']) where 'some_extra' is not listed in the distribution's 'Provides-Extra' metadata / requires.txt extra sections; dm[safe_extra(ext)] raises KeyError which is wrapped into UnknownExtra.
Common situations: Typos in the extra name (e.g. 'tests' vs 'test'), requesting an extra the installed version no longer provides, or depending on an extra from a different package version than expected.
Related errors
- Missing 'Version:' header and/or {} file at path: {}
- Requested {ireq} has inconsistent Provides-Extra between its
- invalid sysconfig.get_config_var('EXT_SUFFIX')
- on non-Android platforms, the api_level and abi arguments ar
- name is invalid: {name!r}
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/75712b5502be8b7d.json.
Report an issue: GitHub.