pypa/pip · error · InstallationError
Editable requirements are not allowed as constraints
Error message
Editable requirements are not allowed as constraints
What it means
InstallationError from check_invalid_constraint_type when a constraint entry is editable ('-e ./pkg' or '-e git+...'). Editable installs cannot act as constraints because a constraint only narrows version selection for a named project; an editable is an install instruction. The resolver rejects it (with a preceding deprecation notice) rather than silently misinterpreting it.
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 d7d0d0a394)
Solutions
- Remove '-e' from any line in the constraints file.
- Move editable installs into the regular requirements file ('-r'), not the constraints file ('-c').
- If you need to pin a local editable, pin the underlying project name+version in the constraint and keep '-e' on the install side.
- Re-run pip after editing to confirm.
Example fix
# before — constraints.txt -e ./local/mylib # after — move to requirements.txt -e ./local/mylib # and in constraints.txt keep only: mylib==1.0
Defensive patterns
Strategy: validation
Validate before calling
def constraints_have_no_editable(path: str) -> bool:
bad = [l.strip() for l in open(path) if l.strip().startswith('-e ')]
if bad:
print(f'editable in constraints: {bad}'); return False
return True Type guard
def is_non_editable_constraint(line: str) -> bool:
return not line.strip().startswith('-e ') Try / catch
if not constraints_have_no_editable('constraints.txt'):
print('move -e lines out of constraints file')
else:
run_pip(['install', '-c', 'constraints.txt', 'pkg']) Prevention
- Never put '-e' lines in a constraints file.
- Separate install requirements (-r) from constraints (-c) physically.
- Lint for '-e' in constraints in CI.
When it happens
Trigger: A file passed with '-c' contains a line like '-e ./local/pkg' or '-e git+https://.../pkg.git'. collect_root_requirements calls check_invalid_constraint_type, req.editable is True, and the problem string is raised.
Common situations: Reusing a monorepo dev-requirements file as both install and constraints; copy-pasting an editable line into a constraints file by mistake; teams merging a constraints file and a dev-install file.
Related errors
- Unnamed requirements are not allowed as constraints
- Constraints cannot have extras
- Editable requirements are not allowed as constraints
- Could not satisfy constraints for '{install_req.name}': inst
- Need exactly one file to operate upon (--user, --site, --glo
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/4d9c74eb03576191.json.
Report an issue: GitHub.