pypa/pip · error · CommandError

Failed to build one or more wheels

Error message

Failed to build one or more wheels

What it means

Raised by the wheel command after the build phase completes if build_failures is non-empty. Failures accumulate from two sources: the build() call failing to produce a wheel for one or more requirements, and OSError failures when copying successfully-built wheels to the output directory. The message is generic because it aggregates potentially many distinct failures whose details are in the preceding log output.

Solutions

  1. Re-run with -v / --verbose to see the per-requirement build error that preceded this summary.
  2. Install required build tools (compiler, dev headers) for C-extension packages, or use --prefer-binary to fetch a prebuilt wheel.
  3. Ensure --wheel-dir points to a writable directory with adequate disk space.
  4. If building from source with build isolation failing, inspect whether pyproject.toml build-system.requires can be satisfied (check network / index availability).
  5. Try `pip wheel --no-build-isolation <pkg>` only if the build deps are already installed in the current environment.

Example fix

# before (fails, generic message)
pip wheel numpy
# after (verbose to see real error, prefer binary)
pip wheel -v --prefer-binary numpy
Defensive patterns

Strategy: try-catch

Validate before calling

import os, shutil

def precheck_wheel_build(wheel_dir: str, prefer_binary: bool, has_compiler: bool) -> None:
    if not os.path.isdir(wheel_dir) or not os.access(wheel_dir, os.W_OK):
        raise RuntimeError(f'--wheel-dir {wheel_dir} is not writable')
    if not prefer_binary and not has_compiler:
        raise RuntimeError('No C compiler available; pass --prefer-binary to use prebuilt wheels')

Try / catch

import subprocess
try:
    subprocess.run(['pip', 'wheel', '-v', pkg], check=True)
except subprocess.CalledProcessError:
    # inspect verbose log, then fall back to a prebuilt wheel
    subprocess.run(['pip', 'wheel', '--prefer-binary', pkg], check=True)

Prevention

When it happens

Trigger: Running `pip wheel <pkg>` where the package's build backend fails (missing compiler, broken setup.py/pyproject.toml, incompatible build deps), or where the output directory (--wheel-dir) is not writable causing the shutil.copy to raise OSError.

Common situations: Building a C-extension package without a C compiler or development headers; building from an sdist whose pyproject.toml declares build deps unavailable offline; pointing --wheel-dir at a read-only or full filesystem; network-isolated builds where build dependencies cannot be fetched.

Related errors


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

Appendix: source

Thrown at src/pip/_internal/commands/wheel.py:175

            verify=(not options.no_verify),
            allow_editables=False,
        )
        for req in build_successes:
            assert req.link and req.link.is_wheel
            assert req.local_file_path
            # copy from cache to target directory
            try:
                shutil.copy(req.local_file_path, options.wheel_dir)
            except OSError as e:
                logger.warning(
                    "Failed to copy built wheel %s to %s: %s",
                    req.name,
                    options.wheel_dir,
                    e,
                )
                build_failures.append(req)
        if len(build_failures) != 0:
            raise CommandError("Failed to build one or more wheels")

        return SUCCESS

View on GitHub (pinned to f399c37189)