pypa/pip · error · InstallationError

Unknown scheme key used in

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 by make_data_scheme_file when the .data subdirectory name (scheme_key) is not one of the recognised scheme keys (purelib, platlib, headers, scripts, data). Because the key maps to no install location, pip cannot place the file and aborts.

Solutions

  1. Upgrade pip to a version that recognises the scheme key if it is legitimately new.
  2. Rebuild the wheel using a standard build backend so it only emits valid scheme keys.
  3. Inspect the wheel's .data subdirs and correct any invalid key.
Defensive patterns

Strategy: validation

Validate before calling

VALID_SCHEME_KEYS = {"purelib", "platlib", "headers", "scripts", "data"}

def data_scheme_key_valid(record_path: str) -> bool:
    parts = record_path.split("/")
    if len(parts) < 3 or not parts[0].endswith(".data"):
        return True  # not a data-scheme path
    return parts[1] in VALID_SCHEME_KEYS

# assert data_scheme_key_valid("pkg-1.0.data/scripts/x")
# assert not data_scheme_key_valid("pkg-1.0.data/wrongkey/x")

Prevention

When it happens

Trigger: The wheel contains 'pkg-1.0.data/<unknownkey>/file'; scheme_paths[scheme_key] raises KeyError, and the valid keys are listed in the error message.

Common situations: A future/new scheme key this pip version does not recognise; a wheel built by a buggy backend that invented a key; typos in hand-made wheels.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/feebd99e96465207. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_internal/operations/install/wheel.py:542

                _, 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 f399c37189)