{"record":{"id":"e639525e126e925d","repo":"pypa/pip","slug":"resolution-too-deep","errorCode":"resolution-too-deep","errorMessage":"Dependency resolution exceeded maximum depth","messagePattern":"Dependency resolution exceeded maximum depth","errorType":"exception","errorClass":"ResolutionTooDeepError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/resolution/resolvelib/resolver.py","lineNumber":114,"sourceCode":"        resolver: RLResolver[Requirement, Candidate, str] = RLResolver(\n            provider,\n            reporter,\n        )\n\n        try:\n            limit_how_complex_resolution_can_be = 200000\n            result = self._result = resolver.resolve(\n                collected.requirements, max_rounds=limit_how_complex_resolution_can_be\n            )\n\n        except ResolutionImpossible as e:\n            error = self.factory.get_installation_error(\n                cast(\"ResolutionImpossible[Requirement, Candidate]\", e),\n                collected.constraints,\n            )\n            raise error from e\n        except ResolutionTooDeep:\n            raise ResolutionTooDeepError from None\n\n        req_set = RequirementSet(check_supported_wheels=check_supported_wheels)\n        # process candidates with extras last to ensure their base equivalent is\n        # already in the req_set if appropriate.\n        # Python's sort is stable so using a binary key function keeps relative order\n        # within both subsets.\n        for candidate in sorted(\n            result.mapping.values(), key=lambda c: c.name != c.project_name\n        ):\n            ireq = candidate.get_install_requirement()\n            if ireq is None:\n                if candidate.name != candidate.project_name:\n                    # extend existing req's extras\n                    with contextlib.suppress(KeyError):\n                        req = req_set.get_requirement(candidate.project_name)\n                        req_set.add_named_requirement(\n                            install_req_extend_extras(\n                                req, get_requirement(candidate.name).extras","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/resolution/resolvelib/resolver.py#L96-L132","documentation":"Raised as ResolutionTooDeepError (pip's own exception, code 'resolution-too-deep') at line 113-114 when the underlying resolvelib RLResolver.resolve() raises ResolutionTooDeep — i.e., the resolver exceeded max_rounds=200000 (line 102-104) without reaching a fixed point. The dependency graph is too complex/exponentially branching for the backtracking resolver to complete within the round budget.","triggerScenarios":"Running pip install on a set of requirements whose dependency graph is pathologically large or contains many overlapping version constraints causing massive backtracking; installing many packages with conflicting or very loose version specifiers simultaneously; environments where prereleases, many extras, and platform markers multiply candidate combinations past 200000 rounds.","commonSituations":"A requirements.txt with unpinned or loosely-pinned (>=) dependencies across many transitive packages; circular-ish or diamond dependency chains with many valid version combinations; an index serving huge numbers of versions for involved packages; an old pip version with a less optimized resolver.","solutions":["Pin the most contested packages to exact versions (==) to drastically prune the backtracking search space.","Upgrade pip to the latest version, which contains resolver performance improvements that reduce rounds.","Reduce simultaneous requirements: install in stages, or trim unused extras from pip install lines.","Add constraints (-c constraints.txt) to cap version ranges for transitive dependencies."],"exampleFix":"// before\npip install pkg-a pkg-b pkg-c pkg-d  # all loosely pinned / unpinned\n\n// after\npip install 'pkg-a==2.1.0' 'pkg-b==1.4.2' pkg-c pkg-d","handlingStrategy":"fallback","validationCode":"def estimate_resolution_risk(req_lines):\n    # heuristic: unpinned (no ==) requirements increase backtracking\n    unpinned = [r for r in req_lines if '==' not in r and '@' not in r]\n    return len(unpinned), len(unpinned) > 5","typeGuard":null,"tryCatchPattern":"import subprocess, sys\ntry:\n    subprocess.run([sys.executable, '-m', 'pip', 'install', *reqs], check=True)\nexcept subprocess.CalledProcessError as e:\n    if 'resolution-too-deep' in (e.stdout or '') + (e.stderr or ''):\n        # retry with exact pins / constraints\n        subprocess.run([sys.executable, '-m', 'pip', 'install', *pinned_reqs], check=True)\n    raise","preventionTips":["Pin high-fanout transitive dependencies to exact versions in a constraints file.","Keep pip up to date for resolver performance improvements.","Install large requirement sets in stages to shrink the per-run graph."],"tags":["pip","resolver","dependency","resolution","resolution-too-deep"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}