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
- Identify which package's metadata contains the bad string (the comes_from / dependency chain context helps)
- Pin to a different version of the offending package that has valid metadata
- Upgrade pip to get a newer vendored packaging library that supports the syntax
- 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
- Pin packages to versions known to have valid metadata
- Upgrade pip to ensure the vendored packaging library supports modern PEP 508 features
- Report broken metadata to the upstream package maintainer
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
- Invalid requirement
- Invalid requirement
- Multiple blocks found in
- Requested has invalid metadata: Requires-Dist in
- Badly formatted data
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)