JuliusBrussee/caveman · error · ValueError

bedrock endpoint must be runtime or mantle

Error message

bedrock endpoint must be runtime or mantle

What it means

The SDK's `bedrock()` descriptor method only accepts two endpoint values: "runtime" (default, first-party gateway prefix `/bedrock`) or "mantle" (explicit opt-in, prefix `/bedrock/anthropic`). Any other string fails this whitelist check. The method is purely descriptive — it builds a dict and performs no network call — so the validation happens entirely client-side before any request is made.

Solutions

  1. Change the endpoint argument to exactly "runtime" or "mantle" (lowercase).
  2. Normalize any env/config-sourced value: `endpoint = (os.environ.get("BEDROCK_ENDPOINT") or "runtime").strip().lower()` and verify it is in {"runtime","mantle"} before calling.
  3. Omit the argument entirely to get the default "runtime" endpoint.

Example fix

// before
info = client.bedrock(endpoint="anthropic")
// after
info = client.bedrock(endpoint="mantle")  # or "runtime"
Defensive patterns

Strategy: validation

Validate before calling

ENDPOINTS = {"runtime", "mantle"}
endpoint = (raw or "runtime").strip().lower()
if endpoint not in ENDPOINTS:
    raise ValueError(f"endpoint must be one of {sorted(ENDPOINTS)}, got {raw!r}")
info = client.bedrock(endpoint=endpoint)

Type guard

def is_bedrock_endpoint(v: object) -> TypeGuard[str]:
    return isinstance(v, str) and v in {"runtime", "mantle"}

Try / catch

try:
    info = client.bedrock(endpoint=raw)
except ValueError as e:
    log.warning("bad bedrock endpoint %r, defaulting to runtime", raw)
    info = client.bedrock(endpoint="runtime")

Prevention

When it happens

Trigger: Calling `client.bedrock(endpoint="prod")`, `bedrock(endpoint="RUNTIME")` (uppercase), `bedrock(endpoint="")`, or passing a variable read from config/environment that isn't exactly `runtime` or `mantle`.

Common situations: Developers guessing endpoint names (e.g. "anthropic", "gateway", "us-east-1"), copying a region string into the endpoint slot, or loading the endpoint from an env var with different casing or trailing whitespace.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/819b9d038ae13b29. Report an issue: GitHub.

Appendix: source

Thrown at packages/sdk/python/caveman_cloud/core.py:613

        )

    def openai(self, upstream_key: str | None = None) -> "Provider":
        return Provider(self, "/openai/v1", upstream_key)

    def anthropic(self, upstream_key: str | None = None) -> "Provider":
        return Provider(self, "/anthropic", upstream_key)

    def gemini(self, upstream_key: str | None = None) -> "Provider":
        return Provider(self, "/gemini", upstream_key)

    def bedrock(self, region: str, *, endpoint: str = "runtime") -> dict[str, Any]:
        """Describe the first-party Bedrock gateway surface.

        Runtime is the default. Mantle is an explicit opt-in descriptor. This
        method performs no network request and carries no AWS secret.
        """
        if endpoint not in {"runtime", "mantle"}:
            raise ValueError("bedrock endpoint must be runtime or mantle")
        return {
            "region": region,
            "endpoint": endpoint,
            "gateway_prefix": "/bedrock/anthropic" if endpoint == "mantle" else "/bedrock",
            "instrumented": True,
            "sdk_only": False,
        }

    def vertex(self, upstream_key: str | None = None) -> "Provider":
        """Vertex AI client proxied through the gateway (``/vertex`` prefix).

        Routes Google Gemini and Anthropic Claude calls through Caveman for
        metering. ``upstream_key`` is a Google OAuth2 access token (e.g. from
        ``gcloud auth print-access-token`` or Application Default Credentials);
        the gateway forwards it as ``Authorization: Bearer …``. Mirrors the
        TypeScript ``Cave.vertex``.
        """
        return Provider(self, "/vertex", upstream_key)

View on GitHub (pinned to 3ee70a1026)