pypa/pip · error · MissingPyProjectBuildRequires
missing-pyproject-build-system-requires
missing-pyproject-build-system-requires
Error message
Can not process {package} What it means
Raised by load_pyproject_toml (pyproject.py:84) as MissingPyProjectBuildRequires (code: missing-pyproject-build-system-requires) when a pyproject.toml has a [build-system] table but that table lacks the required 'requires' key. PEP 518 mandates that [build-system] must contain 'requires', so pip refuses to build.
Solutions
- Add the 'requires' array to [build-system] listing build dependencies (e.g. setuptools + wheel).
- Remove the [build-system] table entirely so pip applies the setuptools legacy defaults.
- Validate the pyproject.toml with a linter/schema checker before publishing.
Example fix
# before (pyproject.toml) [build-system] build-backend = "setuptools.build_meta" # after [build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta"
Defensive patterns
Strategy: validation
Validate before calling
from pip._internal.utils.compat import tomllib
def build_system_has_requires(pyproject_path: str) -> tuple[bool, str | None]:
with open(pyproject_path, 'rb') as f:
data = tomllib.load(f)
bs = data.get('build-system')
if bs is not None and 'requires' not in bs:
return False, '[build-system] present but missing "requires"'
return True, None Type guard
from typing import Any
def has_build_requires(build_system: dict[str, Any] | None) -> bool:
return build_system is None or isinstance(build_system.get('requires'), list) Try / catch
from subprocess import run, CalledProcessError
try:
run(["pip", "install", target], check=True)
except CalledProcessError:
# Add the requires array to [build-system] then rebuild.
run(["python", "-m", "build", target], check=True) Prevention
- Always include 'requires' in [build-system] when declaring a backend.
- Lint pyproject.toml against the PEP 518/621 schema in CI.
- Prefer modern project templates (e.g. setuptools [project]) that include build-system.
When it happens
Trigger: A pyproject.toml containing '[build-system]' with only 'build-backend' (or 'backend-path') and no 'requires' array. The check 'if "requires" not in build_system' fires.
Common situations: Hand-authored pyproject.toml where the author listed a backend but forgot the requires; migration artifacts where build-system was partially populated; tooling that writes backend-path without requires.
Related errors
- invalid-pyproject-build-system-requires
- does not appear to be a Python project: neither 'setup.py'…
- An error occurred while writing to the configuration file
- Configuration file contains invalid
- Configuration file could not be loaded.\n
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/e53ec9e9c7836b89.
Report an issue: GitHub.
Appendix: 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 f399c37189)