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

  1. Check the distribution's metadata (pip show <pkg>, or its METADATA 'Provides-Extra' lines) for the exact extra names it supports.
  2. Correct the extra name spelling/casing in your call to requires().
  3. 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

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


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/75712b5502be8b7d.json. Report an issue: GitHub.