pypa/pip · error · InstallationError

Constraints cannot have extras

Error message

Constraints cannot have extras

What it means

check_invalid_constraint_type (req_install.py:815-816) and collect_root_requirements (factory.py:551-553) reject constraint entries that carry extras (e.g. pkg[extra]==1.0). Extras select optional dependencies and are not a version constraint, so the new resolver forbids extras in -c constraint files.

Solutions

  1. Remove the extras bracket from the constraint line: pkg==1.0.
  2. Put pkg[extra] (with extras) in the main requirements file and keep only pkg==1.0 in the constraints file.

Example fix

# before (constraints.txt)
pkg[test]==1.0
# after
# constraints.txt:
pkg==1.0
# requirements.txt:
pkg[test]
Defensive patterns

Strategy: validation

Validate before calling

# Validate a constraints file has no extras in package specs.
import re
for line in open("constraints.txt"):
    s = line.strip()
    if not s or s.startswith("#"):
        continue
    if re.search(r"[A-Za-z0-9._-]+\[[^\]]+\]", s):
        print(f"Extras not allowed in constraints: {s}")

Prevention

When it happens

Trigger: A constraints file (-c) contains a line like `pkg[extra]==1.0`.

Common situations: Copy-pasting a requirements line with extras into a constraints file; expecting constraints to also enable optional deps.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/a7009b949f806d6c. 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)