pypa/pip · error · InvalidInstalledPackage

invalid-installed-package

invalid-installed-package

Error message

Cannot process installed package {dist} in {installed_location!r} because it has an invalid {invalid_type}:
{invalid_exc.args[0]}

What it means

AlreadyInstalledCandidate.iter_dependencies (candidates.py:424-428) parses the installed distribution's Requires-Dist; if a dependency string raises InvalidRequirement, pip raises InvalidInstalledPackage (code invalid-installed-package, invalid_type='requirement'). Since pip 24.1, installed packages with invalid dependency metadata can no longer be processed by the resolver.

Source

Thrown at src/pip/_internal/resolution/resolvelib/candidates.py:428

            self._version = self.dist.version
        return self._version

    @property
    def is_editable(self) -> bool:
        return self.dist.editable

    def format_for_error(self) -> str:
        return f"{self.name} {self.version} (Installed)"

    def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]:
        if not with_requires:
            return

        try:
            for r in self.dist.iter_dependencies():
                yield from self._factory.make_requirements_from_spec(str(r), self._ireq)
        except InvalidRequirement as exc:
            raise InvalidInstalledPackage(dist=self.dist, invalid_exc=exc) from None

    def get_install_requirement(self) -> InstallRequirement | None:
        return None


class ExtrasCandidate(Candidate):
    """A candidate that has 'extras', indicating additional dependencies.

    Requirements can be for a project with dependencies, something like
    foo[extra].  The extras don't affect the project/version being installed
    directly, but indicate that we need additional dependencies. We model that
    by having an artificial ExtrasCandidate that wraps the "base" candidate.

    The ExtrasCandidate differs from the base in the following ways:

    1. It has a unique name, of the form foo[extra]. This causes the resolver
       to treat it as a separate node in the dependency graph.
    2. When we're getting the candidate's dependencies,

View on GitHub (pinned to f399c37189)

Solutions

  1. Uninstall the offending package so the resolver uses a fresh candidate.
  2. Reinstall a version of the package whose metadata is PEP 508 compliant.
  3. Temporarily pin pip below 24.1 while you remediate the bad package.

Example fix

# before
pip install otherpkg   # fails because installed badpkg has invalid Requires-Dist
# after
pip uninstall badpkg && pip install badpkg==<fixed-version> && pip install otherpkg
Defensive patterns

Strategy: validation

Validate before calling

# Scan installed packages for invalid Requires-Dist before resolving.
import importlib.metadata as md
from packaging.requirements import Requirement, InvalidRequirement
bad = []
for dist in md.distributions():
    for req in (dist.requires or []):
        try:
            Requirement(req)
        except InvalidRequirement:
            bad.append((dist.metadata["Name"], req))
if bad:
    print("Packages with invalid Requires-Dist (uninstall before resolving):", bad)

Prevention

When it happens

Trigger: An already-installed package has a Requires-Dist entry that violates PEP 508; pip 24.1+ encounters it during dependency resolution and refuses to use the installed copy.

Common situations: Old packages installed by a prior pip version that tolerated malformed deps; upgrading pip to 24.1+ suddenly rejects them; vendor-pinned legacy packages.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/bb186ec2830857ca. Report an issue: GitHub.