{"record":{"id":"a00d671b2a7fc2f8","repo":"pypa/pip","slug":"name-has-an-invalid-wheel-e","errorCode":null,"errorMessage":"{name} has an invalid wheel, {e}","messagePattern":"(.+?) has an invalid wheel, (.+?)","errorType":"exception","errorClass":"UnsupportedWheel","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/metadata/pkg_resources.py","lineNumber":151,"sourceCode":"            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\n        elif self.location:\n            location = self.location","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/metadata/pkg_resources.py#L133-L169","documentation":"Raised as UnsupportedWheel from Distribution.from_wheel in pkg_resources.py:150-151. After the wheel zip is opened successfully, parsing the dist-info metadata (parse_wheel / read_wheel_metadata_file) may raise UnsupportedWheel for various malformations; pip re-raises with the package name prefixed so the offending wheel is identified.","triggerScenarios":"Distribution.from_wheel in the pkg_resources backend: the zip opens fine but parse_wheel or read_wheel_metadata_file raises UnsupportedWheel (e.g. missing/invalid WHEEL or METADATA inside), caught and re-raised as UnsupportedWheel(f\"{name} has an invalid wheel, {e}\").","commonSituations":"A wheel missing the .dist-info directory or its METADATA/WHEEL files; a wheel with a malformed RECORD; a non-standard wheel built by a broken backend.","solutions":["Use a properly built wheel from another source/version.","Rebuild the wheel with a standard backend (setuptools/hatch/poetry) that emits the required dist-info files.","Inspect the wheel with `unzip -l file.whl` to confirm it contains a valid .dist-info directory."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before trusting a wheel, confirm it has a valid dist-info with METADATA/WHEEL:\nimport zipfile\nwith wheel.as_zipfile() as zf:\n    names = zf.namelist()\n    assert any(n.endswith('.dist-info/METADATA') for n in names), 'missing METADATA'\n    assert any(n.endswith('.dist-info/WHEEL') for n in names), 'missing WHEEL'","typeGuard":null,"tryCatchPattern":"from pip._internal.exceptions import UnsupportedWheel\ntry:\n    dist = Distribution.from_wheel(wheel, name)\nexcept UnsupportedWheel as e:\n    if 'invalid wheel' in str(e):\n        # use a properly built wheel\n        ...","preventionTips":["Build wheels with standard backends that emit full dist-info.","Inspect wheels with `unzip -l` before relying on them.","Run twine check on wheels before publishing."],"tags":["wheel","metadata","pkg-resources","malformed"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}