pypa/pip · error · InstallationError

Unnamed requirements are not allowed as constraints

Error message

Unnamed requirements are not allowed as constraints

What it means

InstallationError raised by check_invalid_constraint_type (called from collect_root_requirements) when a requirement marked as a constraint (-c file) has no name — e.g. a URL or a bare path. Constraints may only constrain a named project plus version specifier; an unnamed entry is meaningless as a constraint and the resolver rejects it. A deprecation warning precedes the failure.

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

  1. Open the constraints file and remove or rename any unnamed/URL/path lines.
  2. Replace direct-URL constraints with a named specifier, e.g. 'package==1.2.3', and put the URL on the install side instead.
  3. Move any URL requirement out of the '-c' file into a regular '-r' requirements file.
  4. Re-run pip to confirm no unnamed constraint remains.

Example fix

# before — constraints.txt
https://example.com/packages/foo-1.0.tar.gz

# after
foo==1.0
Defensive patterns

Strategy: validation

Validate before calling

def constraints_have_no_unnamed(path: str) -> bool:
    bad = []
    for line in open(path):
        s = line.strip()
        if not s or s.startswith('#') or s.startswith('-'):
            continue
        if '://' in s or s.endswith(('.whl', '.tar.gz', '.zip')) or '/' in s and '=' not in s.split('/')[0]:
            bad.append(s)
    if bad:
        print(f'unnamed constraints: {bad}')
        return False
    return True

Type guard

def is_named_constraint(line: str) -> bool:
    s = line.strip()
    if not s or s.startswith(('#', '-')):
        return True
    from pip._vendor.packaging.requirements import Requirement
    try:
        r = Requirement(s); return bool(r.name)
    except Exception:
        return False

Try / catch

if not constraints_have_no_unnamed('constraints.txt'):
    print('fix unnamed constraints before pip')
else:
    run_pip(['install', '-c', 'constraints.txt', 'pkg'])

Prevention

When it happens

Trigger: A constraints file (passed via '-c constraints.txt') contains a line like 'https://example.com/pkg.tar.gz' or a local path with no project name, and pip is resolving with the new resolver. check_invalid_constraint_type returns the problem string and collect_root_requirements raises InstallationError.

Common situations: Migrating an old constraints file that listed direct URL pins; mixing install requirements and constraint entries; tooling that writes constraints from a lockfile containing direct references.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/7d4f7b6c5e466aad.json. Report an issue: GitHub.