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

  1. Check the package's declared extras with `dist.extras` or inspect METADATA/requires.txt for valid extra names.
  2. Correct the spelling/casing of the extra name (extras are case-insensitive but must match exactly otherwise).
  3. Update to a version of the package that provides the extra.
  4. 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

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


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)