{"id":"e7a7d1d89fecf011","repo":"pypa/pip","slug":"double-requirement-given-install-req-already-i","errorCode":null,"errorMessage":"Double requirement given: {install_req} (already in {existing_req}, name={install_req.name!r})","messagePattern":"Double requirement given: (.+?) \\(already in (.+?), name=(.+?)\\)","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/resolution/legacy/resolver.py","lineNumber":264,"sourceCode":"\n        try:\n            existing_req: InstallRequirement | None = requirement_set.get_requirement(\n                install_req.name\n            )\n        except KeyError:\n            existing_req = None\n\n        has_conflicting_requirement = (\n            parent_req_name is None\n            and existing_req\n            and not existing_req.constraint\n            and existing_req.extras == install_req.extras\n            and existing_req.req\n            and install_req.req\n            and existing_req.req.specifier != install_req.req.specifier\n        )\n        if has_conflicting_requirement:\n            raise InstallationError(\n                f\"Double requirement given: {install_req} \"\n                f\"(already in {existing_req}, name={install_req.name!r})\"\n            )\n\n        # When no existing requirement exists, add the requirement as a\n        # dependency and it will be scanned again after.\n        if not existing_req:\n            requirement_set.add_named_requirement(install_req)\n            # We'd want to rescan this requirement later\n            return [install_req], install_req\n\n        # Assume there's no need to scan, and that we've already\n        # encountered this for scanning.\n        if install_req.constraint or not existing_req.constraint:\n            return [], existing_req\n\n        does_not_satisfy_constraint = install_req.link and not (\n            existing_req.link and install_req.link.path == existing_req.link.path","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/resolution/legacy/resolver.py#L246-L282","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Find the two entries named in the error (install_req and existing_req) and reconcile them to a single specifier.","If you genuinely need different versions in different contexts, split into separate pip invocations / virtualenvs.","Use a constraints file ('-c') to express a single shared pin instead of repeating the spec.","Re-run pip after removing the duplicate/conflicting line."],"exampleFix":"# before\npip install 'foo<2' 'foo>=2'\n# or requirements.txt:\n#   foo<2\n#   foo>=2\n\n# after — pick one specifier\npip install 'foo<2'","handlingStrategy":"validation","validationCode":"from collections import defaultdict\nfrom pip._vendor.packaging.requirements import Requirement\ndef find_conflicting_specs(req_lines: list[str]) -> dict[str, list[str]]:\n    specs = defaultdict(list)\n    for line in req_lines:\n        s = line.strip()\n        if not s or s.startswith(('#', '-')):\n            continue\n        r = Requirement(s)\n        specs[r.name].append(str(r.specifier))\n    return {n: v for n, v in specs.items() if len(set(v)) > 1}","typeGuard":"def has_no_duplicate_conflicts(req_lines: list[str]) -> bool:\n    return not find_conflicting_specs(req_lines)","tryCatchPattern":"conflicts = find_conflicting_specs(open('requirements.txt').read().splitlines())\nif conflicts:\n    print(f'resolve duplicate/conflicting specs: {conflicts}'); raise SystemExit(1)\nrun_pip(['install', '-r', 'requirements.txt'])","preventionTips":["Keep a single source of truth for each package's specifier.","Use a constraints file to centralize version pins.","Lint requirements files for duplicate names with conflicting specifiers in pre-commit."],"tags":["resolver","conflict","requirements","duplicate","legacy-resolver"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}