{"id":"922f5c6255a691e9","repo":"pypa/pip","slug":"wheel-name-located-at-location-is-invalid-922f5c","errorCode":null,"errorMessage":"Wheel '{name}' located at {location} is invalid.","messagePattern":"Wheel '(.+?)' located at (.+?) is invalid\\.","errorType":"exception","errorClass":"InvalidWheel","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/metadata/pkg_resources.py","lineNumber":149,"sourceCode":"        dist = pkg_resources.DistInfoDistribution(\n            location=filename,\n            metadata=InMemoryMetadata(metadata_dict, filename),\n            project_name=project_name,\n        )\n        return cls(dist)\n\n    @classmethod\n    def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution:\n        try:\n            with wheel.as_zipfile() as zf:\n                info_dir, _ = parse_wheel(zf, name)\n                metadata_dict = {\n                    path.split(\"/\", 1)[-1]: read_wheel_metadata_file(zf, path)\n                    for path in zf.namelist()\n                    if path.startswith(f\"{info_dir}/\")\n                }\n        except zipfile.BadZipFile as e:\n            raise InvalidWheel(wheel.location, name) from e\n        except UnsupportedWheel as e:\n            raise UnsupportedWheel(f\"{name} has an invalid wheel, {e}\")\n        dist = pkg_resources.DistInfoDistribution(\n            location=wheel.location,\n            metadata=InMemoryMetadata(metadata_dict, wheel.location),\n            project_name=name,\n        )\n        return cls(dist)\n\n    @property\n    def location(self) -> str | None:\n        return self._dist.location\n\n    @property\n    def installed_location(self) -> str | None:\n        egg_link = egg_link_path_from_location(self.raw_name)\n        if egg_link:\n            location = egg_link","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/metadata/pkg_resources.py#L131-L167","documentation":"InvalidWheel raised by Distribution.from_wheel() (pkg_resources backend) when wheel.as_zipfile() raises zipfile.BadZipFile, or when an UnsupportedWheel propagates and is re-wrapped. The .whl file is not a valid ZIP (or its internal structure is unparseable), so pkg_resources cannot construct the distribution.","triggerScenarios":"Reached while loading a wheel via the pkg_resources metadata backend: opening the file as a zip fails because it is truncated, corrupt, or not actually a zip. Also re-raises an inner UnsupportedWheel as 'X has an invalid wheel, ...'.","commonSituations":"Corrupted download, partial file in pip cache, a mirror/proxy serving an error page with a .whl extension, or a wheel whose dist-info structure is invalid (re-wrapped UnsupportedWheel).","solutions":["Purge the cache (pip cache purge) and reinstall with --no-cache-dir.","Verify the wheel hash against PyPI to detect corruption.","Re-download directly from PyPI, bypassing mirrors/proxies.","If the inner cause is an unsupported wheel, address that specific metadata issue once the file is valid."],"exampleFix":"# before\npip install ./somepkg-1.0-py3-none-any.whl   # corrupt file\n\n# after\npip cache purge\npip install --no-cache-dir somepkg","handlingStrategy":"validation","validationCode":"import zipfile\ntry:\n    with zipfile.ZipFile(path) as zf:\n        assert zf.testzip() is None\n        # also ensure a .dist-info exists\n        assert any(n.endswith('.dist-info/METADATA') for n in zf.namelist())\n    print('valid wheel')\nexcept (zipfile.BadZipFile, AssertionError):\n    print('invalid wheel')","typeGuard":"def is_valid_wheel(path: str) -> bool:\n    import zipfile\n    try:\n        with zipfile.ZipFile(path) as zf:\n            return zf.testzip() is None and any(\n                n.endswith('.dist-info/METADATA') for n in zf.namelist())\n    except zipfile.BadZipFile:\n        return False","tryCatchPattern":"from pip._internal.exceptions import InvalidWheel, UnsupportedWheel\ntry:\n    dist = Distribution.from_wheel(wheel, name)\nexcept InvalidWheel:\n    # purge cache, re-download\nexcept UnsupportedWheel as e:\n    # inner metadata issue; address specifics\n    ...","preventionTips":["Verify wheel hashes against PyPI before installing.","Purge the pip cache when a corrupt file is suspected.","Re-download with --no-cache-dir from PyPI directly.","Avoid mirrors/proxies that may serve corrupt artifacts."],"tags":["wheel","zipfile","corruption","pkg-resources","cache"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}