{"id":"feebd99e96465207","repo":"pypa/pip","slug":"unknown-scheme-key-used-in-wheel-path-scheme-k","errorCode":null,"errorMessage":"Unknown scheme key used in {wheel_path}: {scheme_key} (for file {record_path!r}). .data directory contents should be in subdirectories named with a valid scheme key ({valid_scheme_keys})","messagePattern":"Unknown scheme key used in (.+?): (.+?) \\(for file (.+?)\\)\\. \\.data directory contents should be in subdirectories named with a valid scheme key \\((.+?)\\)","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/operations/install/wheel.py","lineNumber":536,"sourceCode":"                _, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2)\n            except ValueError:\n                message = (\n                    f\"Unexpected file in {wheel_path}: {record_path!r}. .data directory\"\n                    \" contents should be named like: '<scheme key>/<path>'.\"\n                )\n                raise InstallationError(message)\n\n            try:\n                scheme_path = scheme_paths[scheme_key]\n            except KeyError:\n                valid_scheme_keys = \", \".join(sorted(scheme_paths))\n                message = (\n                    f\"Unknown scheme key used in {wheel_path}: {scheme_key} \"\n                    f\"(for file {record_path!r}). .data directory contents \"\n                    f\"should be in subdirectories named with a valid scheme \"\n                    f\"key ({valid_scheme_keys})\"\n                )\n                raise InstallationError(message)\n\n            dest_path = os.path.join(scheme_path, dest_subpath)\n            assert_no_path_traversal(scheme_path, dest_path)\n            return ZipBackedFile(record_path, dest_path, zip_file)\n\n        return make_data_scheme_file\n\n    def is_data_scheme_path(path: RecordPath) -> bool:\n        return path.split(\"/\", 1)[0].endswith(\".data\")\n\n    paths = cast(list[RecordPath], wheel_zip.namelist())\n    file_paths = filterfalse(is_dir_path, paths)\n    root_scheme_paths, data_scheme_paths = partition(is_data_scheme_path, file_paths)\n\n    make_root_scheme_file = root_scheme_file_maker(wheel_zip, lib_dir)\n    files: Iterator[File] = map(make_root_scheme_file, root_scheme_paths)\n\n    def is_script_scheme_path(path: RecordPath) -> bool:","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/operations/install/wheel.py#L518-L554","documentation":"Raised as InstallationError at wheel.py:526-536 when a file under the *.data directory uses a scheme key that is not one of the recognized SCHEME_KEYS. The code builds scheme_paths from the current Scheme and raises KeyError when looking up scheme_paths[scheme_key], then formats the list of valid keys into the message.","triggerScenarios":"A wheel's *.data directory has a subdirectory name other than the valid scheme keys. E.g. 'mypkg-1.0.data/libfoo/foo.so' where 'libfoo' is not a valid scheme key (valid: purelib, platlib, headers, scripts, data).","commonSituations":"Non-standard build backends or wheels produced by tools that invent custom scheme subdirectories. Manually crafted wheels. Wheels targeting a different platform's scheme layout.","solutions":["Inspect the *.data/ subdirectories of the wheel and compare against the valid scheme keys listed in the error message (purelib, platlib, headers, scripts, data).","Move files into the correct scheme-key subdirectory and rebuild the wheel.","Use a PEP 517-compliant build backend to regenerate the wheel.","Pin to a version of the package whose wheel uses valid scheme keys."],"exampleFix":"# before\nmypkg-1.0.data/libextra/foo.so\n\n# after\nmypkg-1.0.data/platlib/foo.so","handlingStrategy":"validation","validationCode":"from pip._internal.models.scheme import SCHEME_KEYS\nimport zipfile\n\ndef validate_wheel_scheme_keys(whl):\n    with zipfile.ZipFile(whl) as z:\n        for n in z.namelist():\n            if \"/\" in n and n.split(\"/\", 1)[0].endswith(\".data\"):\n                key = n.split(\"/\", 2)[1]\n                if key not in SCHEME_KEYS:\n                    raise ValueError(f\"unknown scheme key '{key}' in {n}; valid: {sorted(SCHEME_KEYS)}\")","typeGuard":"from pip._internal.models.scheme import SCHEME_KEYS\ndef is_valid_scheme_key(record_path: str) -> bool:\n    parts = record_path.split(\"/\", 2)\n    return len(parts) >= 2 and parts[1] in SCHEME_KEYS","tryCatchPattern":null,"preventionTips":["Only use standard scheme subdirectories (purelib, platlib, headers, scripts, data).","Rebuild non-conforming wheels with a compliant backend.","Add a wheel-layout lint step in CI."],"tags":["wheel","packaging","scheme","data-files","install"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}