pypa/pip · error · UnknownExtra
has no such extra feature %r
Error message
%s has no such extra feature %r
What it means
Raised as UnknownExtra in Distribution.requires() at line 3077 when a requested extra name is not found in the dependency map (_dep_map). The code does `dm[safe_extra(ext)]` and catches KeyError, re-raising as UnknownExtra with the distribution and extra name. UnknownExtra is a subclass of Exception (not KeyError).
Solutions
- Check the package's declared extras with `dist.extras` or inspect METADATA/requires.txt for valid extra names.
- Correct the spelling/casing of the extra name (extras are case-insensitive but must match exactly otherwise).
- Update to a version of the package that provides the extra.
- Guard with try/except UnknownExtra before calling require().
Example fix
// before dist.requires(['feuture']) # typo # UnknownExtra: mypackage 1.0 has no such extra feature 'feuture' // after valid = set(dist.extras) dist.requires([e for e in ['feature'] if e in valid])
Defensive patterns
Strategy: validation
Validate before calling
from pkg_resources import safe_extra
def filter_valid_extras(dist, requested_extras):
valid = set(dist.extras)
return [e for e in requested_extras if safe_extra(e) in valid] Type guard
from pkg_resources import safe_extra
def extras_are_valid(dist, extras: list) -> bool:
valid = set(dist.extras)
return all(safe_extra(e) in valid for e in extras)
Try / catch
from pkg_resources import UnknownExtra
try:
reqs = dist.requires(['feature'])
except UnknownExtra:
reqs = dist.requires() # skip extras
Prevention
- Check dist.extras before calling dist.requires() with extra names.
- Use try/except UnknownExtra in plugin systems with optional extras.
- Validate extra names against metadata to catch typos early.
When it happens
Trigger: Calling `dist.requires(['some_extra'])` where 'some_extra' is not defined in the package's metadata (requires.txt / METADATA Provides-Extra). Also triggered via EntryPoint.require() when the entry point references extras that don't exist.
Common situations: Requesting an extra that was misspelled or removed in a newer version; calling require() with extras that were never declared; version mismatch between expected and installed package extras; typo in extras name (e.g. 'all' vs 'ALL').
Related errors
- Duplicate entry point
- Entry points must be listed in groups
- Error decoding metadata for
- Error parsing entry points for
- Invalid section heading
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/75712b5502be8b7d.
Report an issue: GitHub.
Appendix: 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 f399c37189)