pypa/pip · error · InstallationError
Unknown scheme key used in {wheel_path}: {scheme_key} (for f
Error message
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}) What it means
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.
Source
Thrown at src/pip/_internal/operations/install/wheel.py:536
_, scheme_key, dest_subpath = normed_path.split(os.path.sep, 2)
except ValueError:
message = (
f"Unexpected file in {wheel_path}: {record_path!r}. .data directory"
" contents should be named like: '<scheme key>/<path>'."
)
raise InstallationError(message)
try:
scheme_path = scheme_paths[scheme_key]
except KeyError:
valid_scheme_keys = ", ".join(sorted(scheme_paths))
message = (
f"Unknown scheme key used in {wheel_path}: {scheme_key} "
f"(for file {record_path!r}). .data directory contents "
f"should be in subdirectories named with a valid scheme "
f"key ({valid_scheme_keys})"
)
raise InstallationError(message)
dest_path = os.path.join(scheme_path, dest_subpath)
assert_no_path_traversal(scheme_path, dest_path)
return ZipBackedFile(record_path, dest_path, zip_file)
return make_data_scheme_file
def is_data_scheme_path(path: RecordPath) -> bool:
return path.split("/", 1)[0].endswith(".data")
paths = cast(list[RecordPath], wheel_zip.namelist())
file_paths = filterfalse(is_dir_path, paths)
root_scheme_paths, data_scheme_paths = partition(is_data_scheme_path, file_paths)
make_root_scheme_file = root_scheme_file_maker(wheel_zip, lib_dir)
files: Iterator[File] = map(make_root_scheme_file, root_scheme_paths)
def is_script_scheme_path(path: RecordPath) -> bool:View on GitHub (pinned to d7d0d0a394)
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.
Example fix
# before mypkg-1.0.data/libextra/foo.so # after mypkg-1.0.data/platlib/foo.so
Defensive patterns
Strategy: validation
Validate before calling
from pip._internal.models.scheme import SCHEME_KEYS
import zipfile
def validate_wheel_scheme_keys(whl):
with zipfile.ZipFile(whl) as z:
for n in z.namelist():
if "/" in n and n.split("/", 1)[0].endswith(".data"):
key = n.split("/", 2)[1]
if key not in SCHEME_KEYS:
raise ValueError(f"unknown scheme key '{key}' in {n}; valid: {sorted(SCHEME_KEYS)}") Type guard
from pip._internal.models.scheme import SCHEME_KEYS
def is_valid_scheme_key(record_path: str) -> bool:
parts = record_path.split("/", 2)
return len(parts) >= 2 and parts[1] in SCHEME_KEYS Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Unexpected file in {wheel_path}: {record_path!r}. .data dire
- Invalid script entry point: {entry_point} - A callable suffi
- For req: {req_description}. {e.args[0]}
- Invalid script entry point name {entry.name!r}: the script w
- The wheel {wheel_path!r} has a file {target_path!r} trying t
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/feebd99e96465207.json.
Report an issue: GitHub.