pypa/pip · error · InstallationError
Project {self} uses a build backend that is missing the 'bui
Error message
Project {self} uses a build backend that is missing the 'build_editable' hook, so it cannot be installed in editable mode. Consider using a build backend that supports PEP 660. What it means
InstallationError from InstallRequirement.editable_sanity_check: the requirement is editable (-e) but the project's PEP 517 build backend does not expose the 'build_editable' hook defined by PEP 660. pip detects this via supports_pyproject_editable and aborts before trying to call a hook that does not exist, pointing the user at PEP 660.
Source
Thrown at src/pip/_internal/req/req_install.py:511
This is done separately after pyproject.toml loading as the backend
need to be called with the build environment's Python executable,
which can vary."""
self.pep517_backend = ConfiguredBuildBackendHookCaller(
self,
self.unpacked_source_directory,
self._pep517_backend_spec,
backend_path=self._pep517_backend_path,
python_executable=python_executable,
)
def editable_sanity_check(self) -> None:
"""Check that an editable requirement if valid for use with PEP 517/518.
This verifies that an editable has a build backend that supports PEP 660.
"""
if self.editable and not self.supports_pyproject_editable:
raise InstallationError(
f"Project {self} uses a build backend "
f"that is missing the 'build_editable' hook, so "
f"it cannot be installed in editable mode. "
f"Consider using a build backend that supports PEP 660."
)
def prepare_metadata(self, allow_editables: bool) -> None:
"""Ensure that project metadata is available.
Under PEP 517 and PEP 660, call the backend hook to prepare the metadata.
Under legacy processing, call setup.py egg-info.
"""
assert self.source_dir, f"No source dir for {self}"
details = self.name or f"from {self.link}"
assert self.pep517_backend is not None
if self.editable and allow_editables and self.supports_pyproject_editable:
self.metadata_directory = generate_editable_metadata(View on GitHub (pinned to d7d0d0a394)
Solutions
- Upgrade the build backend: require 'setuptools>=64' (and wheel) in [build-system].requires in pyproject.toml.
- Add/repair a pyproject.toml with a PEP 660-capable backend: build-system.backend = 'setuptools.build_meta'.
- If you cannot change the backend, drop '-e' and do a normal install instead.
- Recreate the build environment (pip cache, .egg-info, build/) so the newer backend is actually picked up.
Example fix
# before — pyproject.toml [build-system] requires = ["setuptools<64"] build-backend = "setuptools.build_meta" # pip install -e . -> error # after [build-system] requires = ["setuptools>=64", "wheel"] build-backend = "setuptools.build_meta"
Defensive patterns
Strategy: validation
Validate before calling
def backend_supports_editable(pyproject_path: str) -> bool:
import tomllib
with open(pyproject_path, 'rb') as f:
data = tomllib.load(f)
backend = data.get('build-system', {}).get('build-backend', '')
requires = data.get('build-system', {}).get('requires', [])
pep660_backends = {'setuptools.build_meta', 'hatchling', 'flit_core.buildapi', 'pdm.backend'}
if backend in pep660_backends:
return any('setuptools>=64' in r or 'hatchling' in r or 'flit' in r or 'pdm' in r for r in requires)
return False Type guard
def supports_pep660_editable(pyproject_path: str) -> bool:
return backend_supports_editable(pyproject_path) Try / catch
if editable and not supports_pep660_editable('pyproject.toml'):
print('backend lacks build_editable; install without -e or upgrade backend')
else:
run_pip(['install', '-e', '.']) Prevention
- Pin 'setuptools>=64' in [build-system].requires for editable installs.
- Add a CI job that runs 'pip install -e .' to catch missing build_editable early.
- Keep a modern pyproject.toml with an explicit build-backend.
When it happens
Trigger: 'pip install -e .' (or '-e <vcs url>') for a project whose pyproject.toml declares a build-system.backend (e.g. an old setuptools, a custom backend, or a bare legacy setup.py with no PEP 660 support) lacking the build_editable hook.
Common situations: Old setuptools (<64) in the build environment; a project that only ships setup.py and a minimal/no pyproject.toml; a custom backend that implemented build_wheel but never build_editable; pinning 'setuptools<64' in build-system.requires.
Related errors
- failed-build-dependency-install
- failed-wheel-build-for-install
- venv-creation-error
- failed-wheel-build-for-install
- Failed to build one or more wheels
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/86c606f7a5b52189.json.
Report an issue: GitHub.