{"record":{"id":"7e1c4eed1ee79b01","repo":"pypa/pip","slug":"wheel-is-missing-wheel-version","errorCode":null,"errorMessage":"WHEEL is missing Wheel-Version","messagePattern":"WHEEL is missing Wheel-Version","errorType":"exception","errorClass":"UnsupportedWheel","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/utils/wheel.py","lineNumber":101,"sourceCode":"\n    try:\n        wheel_text = wheel_contents.decode()\n    except UnicodeDecodeError as e:\n        raise UnsupportedWheel(f\"error decoding {path!r}: {e!r}\")\n\n    # FeedParser (used by Parser) does not raise any exceptions. The returned\n    # message may have .defects populated, but for backwards-compatibility we\n    # currently ignore them.\n    return Parser().parsestr(wheel_text)\n\n\ndef wheel_version(wheel_data: Message) -> tuple[int, ...]:\n    \"\"\"Given WHEEL metadata, return the parsed Wheel-Version.\n    Otherwise, raise UnsupportedWheel.\n    \"\"\"\n    version_text = wheel_data[\"Wheel-Version\"]\n    if version_text is None:\n        raise UnsupportedWheel(\"WHEEL is missing Wheel-Version\")\n\n    version = version_text.strip()\n\n    try:\n        return tuple(map(int, version.split(\".\")))\n    except ValueError:\n        raise UnsupportedWheel(f\"invalid Wheel-Version: {version!r}\")\n\n\ndef check_compatibility(version: tuple[int, ...], name: str) -> None:\n    \"\"\"Raises errors or warns if called with an incompatible Wheel-Version.\n\n    pip should refuse to install a Wheel-Version that's a major series\n    ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when\n    installing a version only minor version ahead (e.g 1.2 > 1.1).\n\n    version: a 2-tuple representing a Wheel-Version (Major, Minor)\n    name: name of wheel or package to raise exception about","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/utils/wheel.py#L83-L119","documentation":"Raised by wheel_version() when the parsed WHEEL metadata message has no 'Wheel-Version' header. The Wheel-Version field is mandatory in the wheel format spec; its absence means the metadata file is incomplete or malformed.","triggerScenarios":"Calling wheel_version(wheel_data) where wheel_data['Wheel-Version'] returns None. Reached during wheel installation via parse_wheel() after the WHEEL file is successfully read and decoded.","commonSituations":"A hand-authored or tool-generated WHEEL file missing the Wheel-Version line. A wheel built by a non-standard or experimental build backend. A corrupt or partially-written WHEEL file.","solutions":["Inspect the WHEEL file: 'unzip -p <file>.whl \"*.dist-info/WHEEL\"'","Rebuild the wheel with a compliant build backend (setuptools, hatchling, flit)","Ensure the WHEEL file contains 'Wheel-Version: 1.0'","Re-download from the official PyPI index"],"exampleFix":"// before\n# WHEEL file missing Wheel-Version line\nWheel-Version: \nGenerator: custom\n// after\nWheel-Version: 1.0\nGenerator: setuptools (68.0.0)\nRoot-Is-Purelib: true\nTag: py3-none-any","handlingStrategy":"validation","validationCode":"import zipfile\nfrom email.parser import Parser\n\ndef wheel_has_version(path: str) -> bool:\n    with zipfile.ZipFile(path) as zf:\n        for name in zf.namelist():\n            if name.endswith('.dist-info/WHEEL'):\n                msg = Parser().parsestr(zf.read(name).decode())\n                return msg['Wheel-Version'] is not None\n    return False","typeGuard":"from email.message import Message\n\ndef has_wheel_version(metadata: Message) -> bool:\n    return metadata.get('Wheel-Version') is not None","tryCatchPattern":"from pip._internal.exceptions import UnsupportedWheel\n\ntry:\n    wheel_version(metadata)\nexcept UnsupportedWheel as e:\n    if 'missing Wheel-Version' in str(e):\n        raise PackagingError(f'wheel metadata incomplete: {e}')\n    raise","preventionTips":["Build wheels with compliant backends that always emit Wheel-Version","Verify WHEEL file contents: 'unzip -p <file>.whl *.dist-info/WHEEL'","Ensure the WHEEL file includes 'Wheel-Version: 1.0'","Use standard build tools rather than hand-assembling wheels"],"tags":["wheel","metadata","wheel-version","packaging","installation"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}