{"id":"0eac9f25c945dbe1","repo":"pypa/pip","slug":"error-decoding-metadata-for-wheel-e-in-filen","errorCode":null,"errorMessage":"Error decoding metadata for {wheel}: {e} in {filename} file","messagePattern":"Error decoding metadata for (.+?): (.+?) in (.+?) file","errorType":"exception","errorClass":"UnsupportedWheel","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/metadata/importlib/_dists.py","lineNumber":93,"sourceCode":"        return cls(files, info_location)\n\n    def iterdir(self, path: InfoPath) -> Iterator[pathlib.PurePosixPath]:\n        # Only allow iterating through the metadata directory.\n        if pathlib.PurePosixPath(str(path)) in self._files:\n            return iter(self._files)\n        raise FileNotFoundError(path)\n\n    def read_text(self, filename: str) -> str | None:\n        try:\n            data = self._files[pathlib.PurePosixPath(filename)]\n        except KeyError:\n            return None\n        try:\n            text = data.decode(\"utf-8\")\n        except UnicodeDecodeError as e:\n            wheel = self.info_location.parent\n            error = f\"Error decoding metadata for {wheel}: {e} in {filename} file\"\n            raise UnsupportedWheel(error)\n        return text\n\n    def locate_file(self, path: str | PathLike[str]) -> pathlib.Path:\n        # This method doesn't make sense for our in-memory wheel, but the API\n        # requires us to define it.\n        raise NotImplementedError\n\n\nclass Distribution(BaseDistribution):\n    def __init__(\n        self,\n        dist: importlib.metadata.Distribution,\n        info_location: BasePath | None,\n        installed_location: BasePath | None,\n    ) -> None:\n        self._dist = dist\n        self._info_location = info_location\n        self._installed_location = installed_location","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/metadata/importlib/_dists.py#L75-L111","documentation":"UnsupportedWheel raised by WheelDistribution.read_text() when a metadata file inside the wheel (METADATA / WHEEL / entry_points etc.) cannot be decoded as UTF-8. The wheel is structurally a valid zip but its metadata bytes are not valid UTF-8, so importlib.metadata cannot parse it.","triggerScenarios":"Reached while reading an in-memory wheel's metadata file: data.decode('utf-8') raises UnicodeDecodeError. The offending filename is included in the message along with the wheel location.","commonSituations":"A wheel built with a non-UTF-8 locale or an old tool that wrote metadata in latin-1/cp1252; a metadata file accidentally containing binary garbage; a corrupt wheel download producing non-UTF-8 bytes.","solutions":["Re-download the wheel (verify its hash) in case of transfer corruption.","Rebuild the wheel with a current build backend (build/hatch/setuptools>=64) that emits UTF-8 metadata.","Report to the package maintainer if a published wheel ships non-UTF-8 metadata.","Force a source install (--no-binary) to bypass the broken wheel."],"exampleFix":"# before - install a wheel with latin-1 METADATA\npip install somepkg-1.0-py3-none-any.whl\n\n# after\npip install --no-binary somepkg somepkg   # build from sdist\n# or rebuild the wheel correctly\npython -m build --wheel","handlingStrategy":"validation","validationCode":"import zipfile\nwith zipfile.ZipFile(wheel_path) as zf:\n    for n in zf.namelist():\n        if n.endswith(('METADATA','RECORD','WHEEL','entry_points.txt')):\n            try:\n                zf.read(n).decode('utf-8')\n            except UnicodeDecodeError:\n                print(f'{n} in {wheel_path} is not UTF-8')","typeGuard":"def wheel_metadata_utf8(path: str) -> bool:\n    import zipfile\n    try:\n        with zipfile.ZipFile(path) as zf:\n            for n in zf.namelist():\n                if n.endswith(('METADATA','WHEEL')):\n                    zf.read(n).decode('utf-8')\n        return True\n    except (UnicodeDecodeError, zipfile.BadZipFile):\n        return False","tryCatchPattern":"from pip._internal.exceptions import UnsupportedWheel\ntry:\n    dist = Distribution.from_wheel(wheel, name)\nexcept UnsupportedWheel as e:\n    if 'decoding metadata' in str(e):\n        # rebuild or re-download the wheel\n        ...","preventionTips":["Build wheels with UTF-8 locale and current backends.","Verify wheel hashes after download to detect corruption.","Use --no-binary to fall back to sdist for legacy wheels.","Report non-UTF-8 metadata to package maintainers."],"tags":["metadata","wheel","encoding","utf-8"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}