pypa/pip · error · InstallationError

Unexpected file in : . .data directory contents should be…

Error message

Unexpected file in {wheel_path}: {record_path!r}. .data directory contents should be named like: '<scheme key>/<path>'.

What it means

Raised as InstallationError by make_data_scheme_file when a file inside the wheel's .data directory cannot be split into '<scheme_key>/<path>' (normed_path.split(os.path.sep, 2) yields fewer than three parts). The .data directory must contain files organised under a scheme-key subdirectory, not flat files.

Solutions

  1. Rebuild the wheel with a standard build backend that produces the correct '<key>/<path>' .data layout.
  2. Inspect the wheel's namelist to confirm .data entries are under a scheme-key subdir.
  3. Use a different/more recent version of the package whose wheel is well-formed.
Defensive patterns

Strategy: validation

Validate before calling

def data_path_well_formed(record_path: str) -> bool:
    # .data entries must be '<anything>.data/<key>/<subpath>'
    parts = record_path.split("/")
    return len(parts) >= 3 and parts[0].endswith(".data")

# assert data_path_well_formed("pkg-1.0.data/scripts/x")
# assert not data_path_well_formed("pkg-1.0.data/flatfile")

Prevention

When it happens

Trigger: The wheel contains a path like 'pkg-1.0.data/flatfile' (a file directly under the .data dir) instead of 'pkg-1.0.data/scripts/flatfile', so the scheme key cannot be extracted.

Common situations: Malformed wheel produced by a non-standard or buggy build backend; manually constructed wheels with a flat .data layout; truncated/corrupt archive.

Related errors


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

Appendix: source

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

            return ZipBackedFile(record_path, dest_path, zip_file)

        return make_root_scheme_file

    def data_scheme_file_maker(
        zip_file: ZipFile, scheme: Scheme
    ) -> Callable[[RecordPath], File]:
        scheme_paths = {key: getattr(scheme, key) for key in SCHEME_KEYS}

        def make_data_scheme_file(record_path: RecordPath) -> File:
            normed_path = os.path.normpath(record_path)
            try:
                _, 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

View on GitHub (pinned to f399c37189)