pypa/pip · error · MissingPyProjectBuildRequires
missing-pyproject-build-system-requires
missing-pyproject-build-system-requires
Error message
Can not process {package} What it means
Raised as MissingPyProjectBuildRequires when a pyproject.toml contains a [build-system] table but that table has no `requires` key. PEP 518 mandates that [build-system].requires be present and list the build dependencies. pip refuses to proceed because it cannot construct the isolated build environment without knowing which build tools to install.
Source
Thrown at src/pip/_internal/pyproject.py:85
build_system = None
if build_system is None:
# In the absence of any explicit backend specification, we
# assume the setuptools backend that most closely emulates the
# traditional direct setup.py execution, and require wheel and
# a version of setuptools that supports that backend.
build_system = {
"requires": ["setuptools>=40.8.0"],
"build-backend": "setuptools.build_meta:__legacy__",
}
# Ensure that the build-system section in pyproject.toml conforms
# to PEP 518.
# Specifying the build-system table but not the requires key is invalid
if "requires" not in build_system:
raise MissingPyProjectBuildRequires(package=req_name)
# Error out if requires is not a list of strings
requires = build_system["requires"]
if not _is_list_of_str(requires):
raise InvalidPyProjectBuildRequires(
package=req_name,
reason="It is not a list of strings.",
)
# Each requirement must be valid as per PEP 508
for requirement in requires:
try:
get_requirement(requirement)
except InvalidRequirement as error:
raise InvalidPyProjectBuildRequires(
package=req_name,
reason=f"It contains an invalid requirement: {requirement!r}",
) from errorView on GitHub (pinned to d7d0d0a394)
Solutions
- Open pyproject.toml and add a requires list under [build-system], e.g. `requires = ["setuptools>=61.0"]`.
- If you use setuptools, also set `build-backend = "setuptools.build_meta"` alongside the requires.
- If you did not mean to declare a custom build backend, remove the entire [build-system] table so pip falls back to the legacy setuptools default (pyproject.py:75).
- Validate the file with a TOML linter or `python -c "import tomllib; print(tomllib.loads(open('pyproject.toml','rb').read().decode()))"`.
Example fix
# before [build-system] build-backend = "setuptools.build_meta" # after [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta"
Defensive patterns
Strategy: validation
Validate before calling
import tomllib
def validate_build_system_requires(path: str = "pyproject.toml") -> None:
with open(path, "rb") as f:
data = tomllib.load(f)
bs = data.get("build-system")
if bs is not None and "requires" not in bs:
raise ValueError("[build-system] is missing the 'requires' key")
validate_build_system_requires() Type guard
null
Try / catch
null
Prevention
- Start pyproject.toml from a known-good template that includes [build-system].requires.
- Add a pre-commit hook that loads pyproject.toml and asserts build-system.requires exists.
- If you don't need a custom backend, omit [build-system] entirely to use the setuptools default.
When it happens
Trigger: A pyproject.toml that declares `[build-system]` with only `build-backend` (or `backend-path`) but omits `requires`. The code path is pyproject.py:84 checking `if 'requires' not in build_system`. Also happens when the table is present but `requires` is set to null or accidentally renamed.
Common situations: Hand-writing a pyproject.toml and forgetting the requires line. Copy-pasting a partial template from a blog post. Migrating from setup.py-only to pyproject.toml and adding [build-system] prematurely. Tooling that autogenerates an incomplete build-system table.
Related errors
- {req_name} does not appear to be a Python project: neither '
- invalid-pyproject-build-system-requires
- Directory {name!r} is not installable. Neither 'setup.py' no
- failed-build-dependency-install
- Invalid script entry point: {entry_point} - A callable suffi
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/e53ec9e9c7836b89.json.
Report an issue: GitHub.