{"id":"34e7d11bea8bf4c7","repo":"pypa/pip","slug":"uninstall-no-record-file","errorCode":"uninstall-no-record-file","errorMessage":"Cannot uninstall {distribution}","messagePattern":"Cannot uninstall (.+?)","errorType":"exception","errorClass":"UninstallMissingRecord","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/req/req_uninstall.py","lineNumber":77,"sourceCode":"    \"\"\"\n    Yield all the uninstallation paths for dist based on RECORD-without-.py[co]\n\n    Yield paths to all the files in RECORD. For each .py file in RECORD, add\n    the .pyc and .pyo in the same directory.\n\n    UninstallPathSet.add() takes care of the __pycache__ .py[co].\n\n    If RECORD is not found, raises an error,\n    with possible information from the INSTALLER file.\n\n    https://packaging.python.org/specifications/recording-installed-packages/\n    \"\"\"\n    location = dist.location\n    assert location is not None, \"not installed\"\n\n    entries = dist.iter_declared_entries()\n    if entries is None:\n        raise UninstallMissingRecord(distribution=dist)\n\n    for entry in entries:\n        path = os.path.join(location, entry)\n        yield path\n        if path.endswith(\".py\"):\n            dn, fn = os.path.split(path)\n            base = fn[:-3]\n            path = os.path.join(dn, base + \".pyc\")\n            yield path\n            path = os.path.join(dn, base + \".pyo\")\n            yield path\n\n\ndef compact(paths: Iterable[str]) -> set[str]:\n    \"\"\"Compact a path set to contain the minimal number of paths\n    necessary to contain all paths in the set. If /a/path/ and\n    /a/path/to/a/file.txt are both in the set, leave only the\n    shorter path.\"\"\"","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/req/req_uninstall.py#L59-L95","documentation":"UninstallMissingRecord (InstallationError subclass with code 'uninstall-no-record-file') raised by uninstallation_paths when the installed distribution has no RECORD file. RECORD (PEP 376/427) lists every file belonging to a dist; without it pip cannot enumerate what to remove and aborts. The error code lets tooling branch on this specific cause.","triggerScenarios":"Running 'pip uninstall <pkg>' where <pkg>'s .dist-info directory has no RECORD (dist.iter_declared_entries() returns None). Common for packages installed by non-pip tools or older installers that did not write RECORD.","commonSituations":"Distutils/easy_install installs; OS-packaged Python wheels installed by the system package manager; packages installed with 'python setup.py install' (legacy); manually copied-in distributions.","solutions":["Reinstall the package with pip first ('pip install --force-reinstall <pkg>') so a proper RECORD is written, then 'pip uninstall <pkg>'.","If the package was installed by your OS package manager, remove it via that manager (apt/dnf/etc.) instead of pip.","Manually locate and remove the .dist-info directory and the package files, then verify with 'pip list'.","Avoid 'python setup.py install' going forward; use 'pip install .'."],"exampleFix":"# before\npip uninstall foo   # UninstallMissingRecord\n\n# after\npip install --force-reinstall foo && pip uninstall foo","handlingStrategy":"try-catch","validationCode":"def has_record(dist_info_dir: str) -> bool:\n    import os\n    return os.path.isfile(os.path.join(dist_info_dir, 'RECORD'))","typeGuard":"def is_pip_uninstallable(dist) -> bool:\n    return dist.iter_declared_entries() is not None","tryCatchPattern":"from pip._internal.exceptions import UninstallMissingRecord\ntry:\n    run_pip(['uninstall', '-y', 'pkg'])\nexcept UninstallMissingRecord:\n    run_pip(['install', '--force-reinstall', '--no-deps', 'pkg'])\n    run_pip(['uninstall', '-y', 'pkg'])","preventionTips":["Install everything via pip so RECORD is always written.","Avoid 'python setup.py install' and OS-package Python wheels you later want pip to remove.","Before uninstall, check the .dist-info has a RECORD file."],"tags":["uninstall","record","pep376","metadata"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}