JuliusBrussee/caveman · error
bedrock Mantle path is not allowed
Error message
bedrock Mantle path %q is not allowed
What it means
The implemented Mantle lane serves exactly two paths: /bedrock/anthropic/v1/messages and /bedrock/anthropic/v1/messages/count_tokens. Any other path under /bedrock/anthropic/ (AWS's OpenAI-compatible Mantle surfaces are deliberately not routed yet) is rejected by mantleActionAllowed in ResolveUpstreamURL.
Solutions
- Use exactly POST /bedrock/anthropic/v1/messages (or .../v1/messages/count_tokens) — check for typos and trailing slashes
- If you need the OpenAI-compatible surface or legacy completions, route via a different provider adapter; Mantle here is Anthropic-Messages-only
- If targeting Bedrock Runtime model invocation, use /bedrock/model/<modelId>/invoke|converse instead
- Upgrade the proxy if a newer Mantle path was recently added to AWS and you need support for it
Example fix
// before POST /bedrock/anthropic/v1/message // typo -> rejected // after POST /bedrock/anthropic/v1/messages
Defensive patterns
Strategy: validation
Validate before calling
allowedMantle := map[string]bool{"/bedrock/anthropic/v1/messages": true, "/bedrock/anthropic/v1/messages/count_tokens": true}
if !allowedMantle[path] {
// correct the path before sending
} Prevention
- Hard-code the two exact Mantle paths in client SDK wrappers
- Avoid OpenAI-style path construction against the /bedrock/anthropic/ mount
- Add an integration test asserting the exact URL used for Mantle calls
When it happens
Trigger: A request like POST /bedrock/anthropic/v1/complete, /bedrock/anthropic/v1/chat/completions, /bedrock/anthropic/v1/models, or a mistyped messages path (e.g. /bedrock/anthropic/v1/message) while endpointKindForPath classifies it as Mantle (prefix /bedrock/anthropic/).
Common situations: Pointing an OpenAI SDK-style client at the Mantle prefix; using the legacy Anthropic /v1/complete endpoint; a trailing-slash or typo variant of /v1/messages; assuming all Anthropic API paths are proxied through Mantle.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- bedrock request path
- bedrock configured endpoint kind
- bedrock endpoint host
- bedrock Mantle endpoint is not enabled
- bedrock Mantle region
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/d5f21e974713aa18.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/providers/bedrock/routing.go:189
if modelID == "" || action == "" {
return nil, fmt.Errorf("bedrock request path %q does not name a model and action", req.URL.Path)
}
if !actionAllowed(action) {
return nil, fmt.Errorf("bedrock action %q is not allowed", action)
}
if !modelAllowed(modelID) {
return nil, fmt.Errorf("bedrock model %q is not on the allowlist", modelID)
}
base.Path = strings.TrimRight(base.Path, "/") + strings.TrimPrefix(req.URL.Path, "/bedrock")
case endpointMantle:
if !env.Bool("CAVE_BEDROCK_MANTLE_ENABLED", false) {
return nil, fmt.Errorf("bedrock Mantle endpoint is not enabled")
}
if !MantleRegionAllowed(region) {
return nil, fmt.Errorf("bedrock Mantle region %q is not on the allowlist", region)
}
if !mantleActionAllowed(req.URL.Path) {
return nil, fmt.Errorf("bedrock Mantle path %q is not allowed", req.URL.Path)
}
base, err = resolveMantleBase(base, region)
if err != nil {
return nil, err
}
base.Path = strings.TrimRight(base.Path, "/") + strings.TrimPrefix(req.URL.Path, "/bedrock")
default:
return nil, fmt.Errorf("bedrock request path %q is not allowed", req.URL.Path)
}
base.RawQuery = req.URL.RawQuery
if env.IsProduction() {
if err := providers.ValidateUpstreamEndpoint(ctx, base, ssrf.ManagedConfig()); err != nil {
return nil, err
}
hostKind, _, ok := bedrockHostKind(base.Hostname())
if !ok || hostKind != kind {
return nil, fmt.Errorf("bedrock endpoint host %q does not match endpoint kind %q", base.Hostname(), kind)View on GitHub (pinned to 3ee70a1026)