{"record":{"id":"e70c7d4079ec78b8","repo":"pypa/pip","slug":"wheel-name-located-at-location-is-invalid","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/importlib/_dists.py","lineNumber":142,"sourceCode":"        project_name: str,\n    ) -> BaseDistribution:\n        # Generate temp dir to contain the metadata file, and write the file contents.\n        temp_dir = pathlib.Path(\n            TempDirectory(kind=\"metadata\", globally_managed=True).path\n        )\n        metadata_path = temp_dir / \"METADATA\"\n        metadata_path.write_bytes(metadata_contents)\n        # Construct dist pointing to the newly created directory.\n        dist = importlib.metadata.Distribution.at(metadata_path.parent)\n        return cls(dist, metadata_path.parent, None)\n\n    @classmethod\n    def from_wheel(cls, wheel: Wheel, name: str) -> BaseDistribution:\n        try:\n            with wheel.as_zipfile() as zf:\n                dist = WheelDistribution.from_zipfile(zf, name, wheel.location)\n        except zipfile.BadZipFile as e:\n            raise InvalidWheel(wheel.location, name) from e\n        return cls(dist, dist.info_location, pathlib.PurePosixPath(wheel.location))\n\n    @property\n    def location(self) -> str | None:\n        if self._info_location is None:\n            return None\n        return str(self._info_location.parent)\n\n    @property\n    def info_location(self) -> str | None:\n        if self._info_location is None:\n            return None\n        return str(self._info_location)\n\n    @property\n    def installed_location(self) -> str | None:\n        if self._installed_location is None:\n            return None","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/metadata/importlib/_dists.py#L124-L160","documentation":"Raised as InvalidWheel from Distribution.from_wheel in _dists.py:141-142 when wheel.as_zipfile() raises zipfile.BadZipFile. The wheel file claims to be a zip but is structurally invalid (truncated, corrupt, or not actually a zip), so it cannot be opened; pip surfaces this as InvalidWheel with the location and name.","triggerScenarios":"Distribution.from_wheel(wheel, name) opens the wheel; the underlying zipfile module detects corruption and raises BadZipFile, which is wrapped and re-raised as InvalidWheel(location, name) (str: \"Wheel '{name}' located at {location} is invalid.\").","commonSituations":"A download interrupted/corrupted by a network drop or proxy; a partial wheel left on disk after a failed install; a file mislabeled with a .whl extension that is not a zip; disk corruption.","solutions":["Clear pip's wheel/cache directory (pip cache purge) and re-download the wheel.","Re-download from the index and verify the file size/hash matches the published values.","If building locally, re-run the build to produce a complete wheel."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before opening, verify the wheel is a valid zip and complete:\nimport zipfile, os\nif not zipfile.is_zipfile(wheel.location):\n    raise SystemExit(f'{wheel.location} is not a valid zip; re-download')\nif os.path.getsize(wheel.location) < expected_size:\n    raise SystemExit('wheel appears truncated; re-download')","typeGuard":null,"tryCatchPattern":"from pip._internal.exceptions import InvalidWheel\ntry:\n    dist = Distribution.from_wheel(wheel, name)\nexcept InvalidWheel:\n    # purge cache and re-download a fresh wheel\n    ...","preventionTips":["Verify wheel hashes/sizes after download.","Purge pip's cache on BadZipFile errors to avoid stale corrupt files.","Use reliable transports/mirrors to avoid truncated downloads."],"tags":["wheel","corruption","zipfile","importlib"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}