{"record":{"id":"819b9d038ae13b29","repo":"JuliusBrussee/caveman","slug":"bedrock-endpoint-must-be-runtime-or-mantle-819b9d","errorCode":null,"errorMessage":"bedrock endpoint must be runtime or mantle","messagePattern":"bedrock endpoint must be runtime or mantle","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"packages/sdk/python/caveman_cloud/core.py","lineNumber":613,"sourceCode":"        )\n\n    def openai(self, upstream_key: str | None = None) -> \"Provider\":\n        return Provider(self, \"/openai/v1\", upstream_key)\n\n    def anthropic(self, upstream_key: str | None = None) -> \"Provider\":\n        return Provider(self, \"/anthropic\", upstream_key)\n\n    def gemini(self, upstream_key: str | None = None) -> \"Provider\":\n        return Provider(self, \"/gemini\", upstream_key)\n\n    def bedrock(self, region: str, *, endpoint: str = \"runtime\") -> dict[str, Any]:\n        \"\"\"Describe the first-party Bedrock gateway surface.\n\n        Runtime is the default. Mantle is an explicit opt-in descriptor. This\n        method performs no network request and carries no AWS secret.\n        \"\"\"\n        if endpoint not in {\"runtime\", \"mantle\"}:\n            raise ValueError(\"bedrock endpoint must be runtime or mantle\")\n        return {\n            \"region\": region,\n            \"endpoint\": endpoint,\n            \"gateway_prefix\": \"/bedrock/anthropic\" if endpoint == \"mantle\" else \"/bedrock\",\n            \"instrumented\": True,\n            \"sdk_only\": False,\n        }\n\n    def vertex(self, upstream_key: str | None = None) -> \"Provider\":\n        \"\"\"Vertex AI client proxied through the gateway (``/vertex`` prefix).\n\n        Routes Google Gemini and Anthropic Claude calls through Caveman for\n        metering. ``upstream_key`` is a Google OAuth2 access token (e.g. from\n        ``gcloud auth print-access-token`` or Application Default Credentials);\n        the gateway forwards it as ``Authorization: Bearer …``. Mirrors the\n        TypeScript ``Cave.vertex``.\n        \"\"\"\n        return Provider(self, \"/vertex\", upstream_key)","sourceCodeStart":595,"sourceCodeEnd":631,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/sdk/python/caveman_cloud/core.py#L595-L631","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Change the endpoint argument to exactly \"runtime\" or \"mantle\" (lowercase).","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.","Omit the argument entirely to get the default \"runtime\" endpoint."],"exampleFix":"// before\ninfo = client.bedrock(endpoint=\"anthropic\")\n// after\ninfo = client.bedrock(endpoint=\"mantle\")  # or \"runtime\"","handlingStrategy":"validation","validationCode":"ENDPOINTS = {\"runtime\", \"mantle\"}\nendpoint = (raw or \"runtime\").strip().lower()\nif endpoint not in ENDPOINTS:\n    raise ValueError(f\"endpoint must be one of {sorted(ENDPOINTS)}, got {raw!r}\")\ninfo = client.bedrock(endpoint=endpoint)","typeGuard":"def is_bedrock_endpoint(v: object) -> TypeGuard[str]:\n    return isinstance(v, str) and v in {\"runtime\", \"mantle\"}","tryCatchPattern":"try:\n    info = client.bedrock(endpoint=raw)\nexcept ValueError as e:\n    log.warning(\"bad bedrock endpoint %r, defaulting to runtime\", raw)\n    info = client.bedrock(endpoint=\"runtime\")","preventionTips":["Keep endpoint values in a module-level Literal/enum constant and reuse it at call sites.","Never pass raw env vars straight in; normalize case and whitespace first.","Use typing.Literal[\"runtime\", \"mantle\"] so type checkers catch bad values."],"tags":["python","validation","enum-argument","bedrock"],"backgroundTag":"invalid-enum-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}