{"record":{"id":"d1918e7025425b8e","repo":"pypa/pip","slug":"requested-ireq-has-inconsistent-requires-dist-be","errorCode":null,"errorMessage":"Requested {ireq} has inconsistent Requires-Dist between its PEP 658 .metadata file and the wheel's METADATA: sidecar has {f_val!r}, wheel has {m_val!r}","messagePattern":"Requested (.+?) has inconsistent Requires-Dist between its PEP 658 \\.metadata file and the wheel's METADATA: sidecar has (.+?), wheel has (.+?)","errorType":"exception","errorClass":"SidecarMetadataInconsistent","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/operations/prepare.py","lineNumber":316,"sourceCode":"    if sidecar_name != wheel_name:\n        raise SidecarMetadataInconsistent(req, \"Name\", sidecar_name, wheel_name)\n\n    if sidecar_dist.version != wheel_dist.version:\n        raise SidecarMetadataInconsistent(\n            req,\n            \"Version\",\n            str(sidecar_dist.version),\n            str(wheel_dist.version),\n        )\n\n    # For multi-use fields, only report the symmetric difference to avoid\n    # unnecessarily flagging matching values.\n    sidecar_requires = _canonical_requires(\n        req, sidecar_dist, \"the PEP 658 .metadata file\"\n    )\n    wheel_requires = _canonical_requires(req, wheel_dist, \"the wheel's METADATA\")\n    if sidecar_requires != wheel_requires:\n        raise SidecarMetadataInconsistent(\n            req,\n            \"Requires-Dist\",\n            \", \".join(sorted(sidecar_requires - wheel_requires)),\n            \", \".join(sorted(wheel_requires - sidecar_requires)),\n        )\n\n    if sidecar_dist.requires_python != wheel_dist.requires_python:\n        raise SidecarMetadataInconsistent(\n            req,\n            \"Requires-Python\",\n            str(sidecar_dist.requires_python),\n            str(wheel_dist.requires_python),\n        )\n\n    sidecar_extras = frozenset(sidecar_dist.iter_provided_extras())\n    wheel_extras = frozenset(wheel_dist.iter_provided_extras())\n    if sidecar_extras != wheel_extras:\n        raise SidecarMetadataInconsistent(","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/operations/prepare.py#L298-L334","documentation":"Raised by _check_sidecar_matches_wheel (prepare.py:315) as SidecarMetadataInconsistent for Requires-Dist. pip canonicalizes the dependency sets from both the sidecar and the wheel and compares them; if the sets differ it reports the symmetric difference (sidecar-only vs wheel-only) and aborts. This catches an index serving dependency metadata that does not match the wheel's actual dependencies.","triggerScenarios":"The set of canonicalized Requires-Dist entries in the PEP 658 .metadata file differs from that in the wheel's METADATA. The message lists entries only in the sidecar vs only in the wheel.","commonSituations":"A republished wheel whose dependencies changed but the mirror's sidecar cache was not invalidated; an index that hand-generates metadata incorrectly; partial mirror synchronization.","solutions":["Switch indexes or use PyPI directly to verify the package is consistent upstream.","Clear the local cache and re-download.","Pin to a known-good version whose metadata is consistent.","Notify the index operator to fix/regenerate the sidecar."],"exampleFix":"# before\npip install --index-url https://mirror/simple pkg\n# after\npip install --no-cache-dir -i https://pypi.org/simple/ 'pkg==1.4.0'","handlingStrategy":"validation","validationCode":"from email.parser import Parser\nfrom pip._vendor.packaging.requirements import Requirement\nimport zipfile, io, requests\n\ndef _canon_set(msg):\n    out = set()\n    for raw in msg.get_all('Requires-Dist', []):\n        r = Requirement(raw.strip())\n        out.add(str(r))\n    return frozenset(out)\n\ndef sidecar_requires_match(wheel_url: str, sidecar_url: str) -> bool:\n    wb = requests.get(wheel_url).content\n    zf = zipfile.ZipFile(io.BytesIO(wb))\n    m_w = Parser().parsestr(zf.read(next(n for n in zf.namelist() if n.endswith('.dist-info/METADATA'))).decode())\n    m_s = Parser().parsestr(requests.get(sidecar_url).text)\n    return _canon_set(m_w) == _canon_set(m_s)","typeGuard":"from pip._vendor.packaging.requirements import Requirement\n\ndef dependency_sets_match(sidecar: list[str], wheel: list[str]) -> bool:\n    def canon(items):\n        return frozenset(str(Requirement(i.strip())) for i in items)\n    return canon(sidecar) == canon(wheel)","tryCatchPattern":"from subprocess import run\n# Fall back to a consistent index on mismatch.\nrun([\"pip\", \"install\", \"--no-cache-dir\", \"-i\", \"https://pypi.org/simple/\", pkg], check=True)","preventionTips":["Validate sidecar vs wheel dependency sets before trusting a mirror in CI.","Pin versions and use trusted indexes.","Mirror operators: keep sidecar and wheel generated from the same build."],"tags":["pep658","metadata","sidecar","requires-dist","index","pip"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}