pypa/pip · error · InstallationError
Invalid requirement
Error message
Invalid requirement: {name!r}: {exc} What it means
Raised by parse_req_from_editable (constructors.py:242) when the project-name portion extracted from an editable requirement string is not a valid PEP 508 requirement name (get_requirement raises InvalidRequirement). The original exception is wrapped as InstallationError with 'Invalid requirement: <name!r>: <exc>'.
Solutions
- Correct the project name to a valid PEP 508 name (letters, digits, _, -, .).
- Use the exact distribution name from the package's metadata.
- Re-run pip install -e '<name> @ <url>' with the corrected name.
Example fix
# before pip install -e 'git+https://github.com/u/repo.git#egg=My Pkg' # after pip install -e 'my-pkg @ git+https://github.com/u/repo.git'
Defensive patterns
Strategy: validation
Validate before calling
from pip._vendor.packaging.requirements import Requirement, InvalidRequirement
import re
def editable_name_is_valid(line: str) -> bool:
# Extract name from PEP 508 form or #egg=...
m = re.match(r'^\s*([^@\s]+)\s*@', line)
name = m.group(1) if m else None
if name is None and '#egg=' in line:
name = line.split('#egg=', 1)[1].split('&')[0].split(';')[0]
if not name:
return False
try:
Requirement(name)
return True
except InvalidRequirement:
return False Type guard
from pip._vendor.packaging.requirements import Requirement, InvalidRequirement
def is_valid_project_name(name: str) -> bool:
try:
Requirement(name)
return True
except InvalidRequirement:
return False Try / catch
from subprocess import run, CalledProcessError
try:
run(["pip", "install", "-e", target], check=True)
except CalledProcessError:
# Correct the name to a valid PEP 508 identifier and retry.
run(["pip", "install", "-e", f"{clean_name} @ {url}"], check=True) Prevention
- Use the canonical distribution name from the package's metadata for editable installs.
- Validate the name part with packaging.requirements before invoking pip.
- Avoid spaces and special characters in #egg= fragments and name@url forms.
When it happens
Trigger: The name parsed out of an editable spec (either the PEP 508 name part or the #egg= fragment) contains illegal characters or syntax — e.g. a name with spaces, dots-as-separators misuse, or invalid characters like '@' inside the name portion.
Common situations: Typos in the egg fragment ('#egg=My Pkg'); using a name that violates PEP 508; a URL accidentally parsed as the name portion.
Related errors
- Could not detect requirement name for
- is not a valid editable requirement. It should either be a…
- Requested has invalid metadata: Requires-Dist in
- [dependency-groups] data was invalid in
- Editable requirements are not allowed as constraints
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/c2475e801e28ef98.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/req/constructors.py:242
return msg
@dataclass(frozen=True)
class RequirementParts:
requirement: Requirement | None
link: Link | None
markers: Marker | None
extras: set[str]
def parse_req_from_editable(editable_req: str) -> RequirementParts:
name, url, extras_override = parse_editable(editable_req)
if name is not None:
try:
req: Requirement | None = get_requirement(name)
except InvalidRequirement as exc:
raise InstallationError(f"Invalid requirement: {name!r}: {exc}")
else:
req = None
link = Link(url)
return RequirementParts(req, link, None, extras_override)
# ---- The actual constructors follow ----
def install_req_from_editable(
editable_req: str,
comes_from: InstallRequirement | str | None = None,
*,
isolated: bool = False,
hash_options: dict[str, list[str]] | None = None,
constraint: bool = False,View on GitHub (pinned to f399c37189)