pypa/pip · error · InstallationError
Unnamed requirements are not allowed as constraints
Error message
Unnamed requirements are not allowed as constraints
What it means
check_invalid_constraint_type (req_install.py:811-812) and collect_root_requirements (factory.py:551-553) reject constraint entries that have no package name (Unnamed requirements). Constraints must be a package name plus an optional version specifier; bare URLs or paths without a name are not allowed because the new resolver cannot key them.
Solutions
- Give the constraint a name using PEP 508 direct reference form: name @ url.
- Move unnamed path/url requirements out of the constraints file into the main requirements file.
- Express the constraint as pkg==<version> only.
Example fix
# before (constraints.txt) git+https://github.com/org/pkg.git # after pkg @ git+https://github.com/org/pkg.git
Defensive patterns
Strategy: validation
Validate before calling
# Validate a constraints file has no unnamed requirements.
import sys
for line in open("constraints.txt"):
s = line.strip()
if not s or s.startswith("#"):
continue
# unnamed if it starts with a path/url indicator and has no 'name @'
if (s.startswith(("http", "git+", "hg+", "svn+", "./", "/", ".."))) and "@" not in s.split()[0]:
print(f"Unnamed constraint not allowed: {s}") Prevention
- Constraints files should only contain 'name==version' style lines.
- Use 'name @ url' direct-reference form if you must reference a URL.
- Keep path/url installs in the requirements file, not constraints.
When it happens
Trigger: A constraints file (-c constraints.txt) contains an unnamed requirement such as a bare URL or a local path without a name.
Common situations: Putting a bare URL or ./local/pkg directly in a constraints file instead of the requirements file.
Related errors
- Constraints cannot have extras
- Could not open file
- Could not satisfy constraints for
- Editable requirements are not allowed as constraints
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/7d4f7b6c5e466aad.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/resolution/resolvelib/factory.py:553
else:
# require the base from the link
yield self.make_requirement_from_candidate(cand)
if ireq.extras:
# require the extras on top of the base candidate
yield self.make_requirement_from_candidate(
self._make_extras_candidate(cand, frozenset(ireq.extras))
)
def collect_root_requirements(
self, root_ireqs: list[InstallRequirement]
) -> CollectedRootRequirements:
collected = CollectedRootRequirements([], {}, {})
for i, ireq in enumerate(root_ireqs):
if ireq.constraint:
# Ensure we only accept valid constraints
problem = check_invalid_constraint_type(ireq)
if problem:
raise InstallationError(problem)
if not ireq.match_markers():
continue
assert ireq.name, "Constraint must be named"
name = canonicalize_name(ireq.name)
if name in collected.constraints:
collected.constraints[name] &= ireq
else:
collected.constraints[name] = Constraint.from_ireq(ireq)
else:
reqs = list(
self._make_requirements_from_install_req(
ireq,
requested_extras=(),
)
)
if not reqs:
continue
template = reqs[0]View on GitHub (pinned to f399c37189)