pypa/pip · error · InstallationError

Double requirement given: {install_req} (already in {existin

Error message

Double requirement given: {install_req} (already in {existing_req}, name={install_req.name!r})

What it means

InstallationError raised by the legacy resolver's _add_requirement_to_set when the same named project is supplied twice as a user requirement with conflicting version specifiers. The resolver detects an existing_req for the same name (same extras, not a constraint) whose specifier differs from the new one and aborts, naming both lines so the user can reconcile them.

Source

Thrown at src/pip/_internal/resolution/legacy/resolver.py:264

        try:
            existing_req: InstallRequirement | None = requirement_set.get_requirement(
                install_req.name
            )
        except KeyError:
            existing_req = None

        has_conflicting_requirement = (
            parent_req_name is None
            and existing_req
            and not existing_req.constraint
            and existing_req.extras == install_req.extras
            and existing_req.req
            and install_req.req
            and existing_req.req.specifier != install_req.req.specifier
        )
        if has_conflicting_requirement:
            raise InstallationError(
                f"Double requirement given: {install_req} "
                f"(already in {existing_req}, name={install_req.name!r})"
            )

        # When no existing requirement exists, add the requirement as a
        # dependency and it will be scanned again after.
        if not existing_req:
            requirement_set.add_named_requirement(install_req)
            # We'd want to rescan this requirement later
            return [install_req], install_req

        # Assume there's no need to scan, and that we've already
        # encountered this for scanning.
        if install_req.constraint or not existing_req.constraint:
            return [], existing_req

        does_not_satisfy_constraint = install_req.link and not (
            existing_req.link and install_req.link.path == existing_req.link.path

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Find the two entries named in the error (install_req and existing_req) and reconcile them to a single specifier.
  2. If you genuinely need different versions in different contexts, split into separate pip invocations / virtualenvs.
  3. Use a constraints file ('-c') to express a single shared pin instead of repeating the spec.
  4. Re-run pip after removing the duplicate/conflicting line.

Example fix

# before
pip install 'foo<2' 'foo>=2'
# or requirements.txt:
#   foo<2
#   foo>=2

# after — pick one specifier
pip install 'foo<2'
Defensive patterns

Strategy: validation

Validate before calling

from collections import defaultdict
from pip._vendor.packaging.requirements import Requirement
def find_conflicting_specs(req_lines: list[str]) -> dict[str, list[str]]:
    specs = defaultdict(list)
    for line in req_lines:
        s = line.strip()
        if not s or s.startswith(('#', '-')):
            continue
        r = Requirement(s)
        specs[r.name].append(str(r.specifier))
    return {n: v for n, v in specs.items() if len(set(v)) > 1}

Type guard

def has_no_duplicate_conflicts(req_lines: list[str]) -> bool:
    return not find_conflicting_specs(req_lines)

Try / catch

conflicts = find_conflicting_specs(open('requirements.txt').read().splitlines())
if conflicts:
    print(f'resolve duplicate/conflicting specs: {conflicts}'); raise SystemExit(1)
run_pip(['install', '-r', 'requirements.txt'])

Prevention

When it happens

Trigger: Running 'pip install "foo<2" "foo>1.5"' or a requirements file containing two 'foo' lines with incompatible specifiers; or one CLI arg plus one requirements-file line for the same package with different versions. has_conflicting_requirement becomes True.

Common situations: Conflicting pins across multiple requirements files combined with '-r'; a script appending requirements dynamically; copy-paste leaving two specs; monorepo where sub-packages disagree and are merged naively.

Related errors


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