pypa/pip · error · InstallationError

Invalid requirement

Error message

Invalid requirement: {req_string!r}: {exc}

What it means

This variant of 'Invalid requirement' comes from install_req_from_req_string(), which is used to build InstallRequirements from already-parsed dependency strings (e.g. from package metadata Requires-Dist, or from resolver/lock-file data). The string failed packaging.requirements.Requirement parsing.

Solutions

  1. Identify which package's metadata contains the bad string (the comes_from / dependency chain context helps)
  2. Pin to a different version of the offending package that has valid metadata
  3. Upgrade pip to get a newer vendored packaging library that supports the syntax
  4. Report the metadata bug to the upstream package maintainer
Defensive patterns

Strategy: try-catch

Validate before calling

from pip._vendor.packaging.requirements import Requirement, InvalidRequirement

def safe_parse_requirement(req_string: str) -> Requirement | None:
    """Returns None if the string is not a valid requirement."""
    try:
        return Requirement(req_string)
    except InvalidRequirement:
        return None

Type guard

from pip._vendor.packaging.requirements import Requirement, InvalidRequirement

def is_parseable_requirement(req_string: str) -> bool:
    """Type guard: True if req_string is valid PEP 508."""
    try:
        Requirement(req_string)
        return True
    except InvalidRequirement:
        return False

Try / catch

from pip._internal.exceptions import InstallationError

try:
    ireq = install_req_from_req_string(req_string, comes_from=parent)
except InstallationError as e:
    logger.error("Bad metadata from %s: %s", parent, e)
    # skip this dependency or pin an alternate version of the parent
    continue

Prevention

When it happens

Trigger: A package's Requires-Dist metadata contains a malformed PEP 508 string. A lock file or pylock file references a requirement string that cannot be parsed. The resolver passes a dependency string that has a syntax error.

Common situations: Upstream package published with broken metadata (rare but happens). A vendored packaging library that is too old to understand newer PEP 508 features like direct URL references. Corrupted or hand-edited lock files. Version mismatch between pip and its vendored packaging.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/req/constructors.py:457

        isolated=isolated,
        hash_options=hash_options,
        config_settings=config_settings,
        constraint=constraint,
        extras=parts.extras,
        user_supplied=user_supplied,
    )


def install_req_from_req_string(
    req_string: str,
    comes_from: InstallRequirement | None = None,
    isolated: bool = False,
    user_supplied: bool = False,
) -> InstallRequirement:
    try:
        req = get_requirement(req_string)
    except InvalidRequirement as exc:
        raise InstallationError(f"Invalid requirement: {req_string!r}: {exc}")

    domains_not_allowed = [
        PyPI.file_storage_domain,
        TestPyPI.file_storage_domain,
    ]
    if (
        req.url
        and comes_from
        and comes_from.link
        and comes_from.link.netloc in domains_not_allowed
    ):
        # Explicitly disallow pypi packages that depend on external urls
        raise InstallationError(
            "Packages installed from PyPI cannot depend on packages "
            "which are not also hosted on PyPI.\n"
            f"{comes_from.name} depends on {req} "
        )

View on GitHub (pinned to f399c37189)