pypa/pip · error · InstallationError
Constraints cannot have extras
Error message
Constraints cannot have extras
What it means
InstallationError from check_invalid_constraint_type when a constraint entry has extras, e.g. 'package[extra]'. Constraints narrow the version of a single project; extras are an install-time selection and cannot be expressed as a constraint, so the resolver rejects the entry (after a deprecation warning).
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
- Strip the '[...]' extras from every line in the constraints file, leaving just 'package<specifier>'.
- Put extras on the install side: in requirements.txt use 'package[test]', in constraints.txt use 'package'.
- Re-generate constraints from your lockfile with extras excluded.
- Re-run pip to confirm no constraint carries extras.
Example fix
# before — constraints.txt requests[socks]==2.31.0 # after requests==2.31.0 # extras belong in requirements.txt, not constraints.txt
Defensive patterns
Strategy: validation
Validate before calling
def constraints_have_no_extras(path: str) -> bool:
import re
bad = [l.strip() for l in open(path) if re.search(r'\[[^\]]+\]', l)]
if bad:
print(f'extras in constraints: {bad}'); return False
return True Type guard
def is_constraint_without_extras(line: str) -> bool:
import re
return not re.search(r'^[^\s#-]\S*\[[^\]]+\]', line.strip()) Try / catch
if not constraints_have_no_extras('constraints.txt'):
print('strip extras from constraints lines')
else:
run_pip(['install', '-c', 'constraints.txt', 'pkg']) Prevention
- Keep extras only on install-side requirements.
- Lint constraints files for '[...]' tokens.
- Document the constraints vs requirements split in your repo README.
When it happens
Trigger: A constraints file ('-c') contains 'package[test]' or 'package[extra1,extra2]'. req.extras is non-empty in check_invalid_constraint_type, the problem string is set, and collect_root_requirements raises.
Common situations: Lockfile tool emitting extras into a constraints file; reusing a dev-requirements file as constraints; combining extras with version pins in the same file.
Related errors
- Unnamed requirements are not allowed as constraints
- 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
- Could not determine appropriate file.
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/a7009b949f806d6c.json.
Report an issue: GitHub.