astral-sh/uv · error · AttributeError

Using `uv.{attr_name}` is not allowed; build backend functio

Error message

Using `uv.{attr_name}` is not allowed; build backend functionality is in the `uv_build` package. Did you mean to use `uv_build` as your build system?

What it means

The `uv` PyPI package intentionally exposes only `find_uv_bin`. Build-backend hooks previously reachable as `uv.build_wheel` etc. moved to the separate `uv_build` package, so the module-level `__getattr__` raises a tailored AttributeError for any of the eight PEP 517 hook names, pointing you at `uv_build`. Any other unknown attribute raises a plain AttributeError instead.

Source

Thrown at python/uv/__init__.py:23

__all__ = ["find_uv_bin"]


def __getattr__(attr_name: str) -> object:
    if attr_name in {
        "build_sdist",
        "build_wheel",
        "build_editable",
        "get_requires_for_build_sdist",
        "get_requires_for_build_wheel",
        "prepare_metadata_for_build_wheel",
        "get_requires_for_build_editable",
        "prepare_metadata_for_build_editable",
    }:
        err = (
            f"Using `uv.{attr_name}` is not allowed; build backend functionality is in the `uv_build` package. "
            f"Did you mean to use `uv_build` as your build system?"
        )
        raise AttributeError(err)
    raise AttributeError(f"module `{__name__}` has no attribute `{attr_name}`")

View on GitHub (pinned to f1a42680ff)

Solutions

  1. Set `build-backend = "uv_build"` in pyproject.toml.
  2. Set `requires = ["uv_build>=0.5,<0.6"]` (or the matching minor range) in `[build-system]` so the correct package is installed in build isolation.
  3. If code called the hooks directly, depend on `uv-build` and `import uv_build` instead of `uv`.

Example fix

# before (pyproject.toml)
[build-system]
requires = ["uv>=0.4"]
build-backend = "uv.build_wheel"

# after
[build-system]
requires = ["uv_build>=0.5,<0.6"]
build-backend = "uv_build"
Defensive patterns

Strategy: validation

Validate before calling

import tomllib

with open("pyproject.toml", "rb") as fh:
    backend = tomllib.load(fh)["build-system"]["build-backend"]
assert backend == "uv_build" or backend.startswith("uv_build:"), (
    f"unsupported backend {backend!r}: build hooks live in the uv_build package, not uv"
)

Type guard

LEGACY_UV_HOOKS = {
    "build_sdist", "build_wheel", "build_editable",
    "get_requires_for_build_sdist", "get_requires_for_build_wheel",
    "prepare_metadata_for_build_wheel", "get_requires_for_build_editable",
    "prepare_metadata_for_build_editable",
}

def is_valid_uv_backend(backend: str) -> bool:
    """True for the supported `uv_build` backend (with optional :target suffix)."""
    name = backend.split(":", 1)[0]
    return name == "uv_build" and name not in LEGACY_UV_HOOKS

Try / catch

try:
    hook = getattr(backend_module, hook_name)
except AttributeError as exc:
    if "uv_build" in str(exc):
        raise SystemExit("Fix pyproject.toml: build-backend = \"uv_build\"") from exc
    raise

Prevention

When it happens

Trigger: `pyproject.toml` with `build-backend = "uv.build_wheel"` (or `uv.build_sdist`, `uv.build_editable`, `uv.get_requires_for_build_*`, `uv.prepare_metadata_for_build_*`), which makes the PEP 517 frontend do `getattr(uv, hook_name)`; also direct code like `import uv; uv.build_wheel(wheel_dir)`.

Common situations: Projects created when uv shipped the backend inside the `uv` package (early 0.4/0.5 era) or templates/tutorials from that period; upgrading uv without updating `[build-system]`; a backend string typo that starts with `uv.` instead of `uv_build`.

Related errors


AI-assisted analysis of astral-sh/uv@f1a42680ff (2026-08-16). Data as JSON: /api/errors/dc71960e37a3d75c. Report an issue: GitHub.