pypa/pip · error · InstallationError
Could not detect requirement name for
Error message
Could not detect requirement name for '{editable_req}', please specify one with your_package_name @ URL What it means
Raised by parse_editable (constructors.py:166) when an editable VCS URL has no detectable project name (no #egg= fragment and no PEP 508 'name @ url' form) and the URL is not a file: path (from which a name can be inferred). pip needs a name for the InstallRequirement, so it asks the user to supply one explicitly.
Solutions
- Use PEP 508 direct-URL form: 'pip install -e "projectname @ git+https://.../repo.git"'.
- Or add the legacy egg fragment: 'pip install -e git+https://.../repo.git#egg=projectname'.
- Check the package's setup.cfg/pyproject.toml [project].name and use exactly that name.
Example fix
# before pip install -e git+https://github.com/user/repo.git # after (PEP 508 form) pip install -e 'myproject @ git+https://github.com/user/repo.git' # or legacy egg fragment pip install -e git+https://github.com/user/repo.git#egg=myproject
Defensive patterns
Strategy: validation
Validate before calling
from pip._vendor.packaging.requirements import Requirement, InvalidRequirement
from urllib.parse import urlparse
def editable_has_name(line: str) -> bool:
# PEP 508 form: 'name @ url'
try:
r = Requirement(line)
if r.url and r.name:
return True
except InvalidRequirement:
pass
# legacy form: '...#egg=Name'
if '#egg=' in line:
return True
return False Type guard
def editable_has_explicit_name(line: str) -> bool:
return ('@ ' in line and not line.startswith('@')) or '#egg=' in line Try / catch
from subprocess import run, CalledProcessError
try:
run(["pip", "install", "-e", vcs_url], check=True)
except CalledProcessError:
# Retry with explicit name: 'name @ url'.
run(["pip", "install", "-e", f"{name} @ {vcs_url}"], check=True) Prevention
- Always provide the project name for VCS editable installs (PEP 508 'name @ url' preferred).
- Use the exact [project].name from the target package.
- Prefer PEP 508 direct-URL form over legacy #egg= fragments.
When it happens
Trigger: An editable VCS requirement like '-e git+https://.../repo.git' without a '#egg=RepoName' fragment or a 'RepoName @ git+https://...' form, where package_name stays None and the link is not file:.
Common situations: Old-style egg fragments removed during a refactor; copy-pasting a bare git URL after -e; migrating from pip syntax to PEP 508 direct-url syntax.
Related errors
- Invalid requirement
- is not a valid editable requirement. It should either be a…
- Requested has invalid metadata: Requires-Dist in
- Can't verify hashes for these requirements because we don't…
- [dependency-groups] data was invalid in
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/8c05bbbbbec00b0e.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/req/constructors.py:167
"""
try:
package_name, url, extras = _parse_direct_url_editable(editable_req)
except ValueError:
package_name, url, extras = _parse_pip_syntax_editable(editable_req)
link = Link(url)
if not link.is_vcs and not link.url.startswith("file:"):
backends = ", ".join(vcs.all_schemes)
raise InstallationError(
f"{editable_req} is not a valid editable requirement. "
f"It should either be a path to a local project or a VCS URL "
f"(beginning with {backends})."
)
# The project name can be inferred from local file URIs easily.
if not package_name and not link.url.startswith("file:"):
raise InstallationError(
f"Could not detect requirement name for '{editable_req}', "
"please specify one with your_package_name @ URL"
)
return package_name, url, extras
def check_first_requirement_in_file(filename: str) -> None:
"""Check if file is parsable as a requirements file.
This is heavily based on ``pkg_resources.parse_requirements``, but
simplified to just check the first meaningful line.
:raises InvalidRequirement: If the first meaningful line cannot be parsed
as an requirement.
"""
with open(filename, encoding="utf-8", errors="ignore") as f:
# Create a steppable iterator, so we can handle \-continuations.
lines = (View on GitHub (pinned to f399c37189)