{"record":{"id":"8be7a04322647ca4","repo":"JuliusBrussee/caveman","slug":"bedrock-request-path-q-is-not-allowed","errorCode":null,"errorMessage":"bedrock request path %q is not allowed","messagePattern":"bedrock request path %q is not allowed","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/bedrock/routing.go","lineNumber":197,"sourceCode":"\t\t}\n\t\tbase.Path = strings.TrimRight(base.Path, \"/\") + strings.TrimPrefix(req.URL.Path, \"/bedrock\")\n\tcase endpointMantle:\n\t\tif !env.Bool(\"CAVE_BEDROCK_MANTLE_ENABLED\", false) {\n\t\t\treturn nil, fmt.Errorf(\"bedrock Mantle endpoint is not enabled\")\n\t\t}\n\t\tif !MantleRegionAllowed(region) {\n\t\t\treturn nil, fmt.Errorf(\"bedrock Mantle region %q is not on the allowlist\", region)\n\t\t}\n\t\tif !mantleActionAllowed(req.URL.Path) {\n\t\t\treturn nil, fmt.Errorf(\"bedrock Mantle path %q is not allowed\", req.URL.Path)\n\t\t}\n\t\tbase, err = resolveMantleBase(base, region)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbase.Path = strings.TrimRight(base.Path, \"/\") + strings.TrimPrefix(req.URL.Path, \"/bedrock\")\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"bedrock request path %q is not allowed\", req.URL.Path)\n\t}\n\tbase.RawQuery = req.URL.RawQuery\n\n\tif env.IsProduction() {\n\t\tif err := providers.ValidateUpstreamEndpoint(ctx, base, ssrf.ManagedConfig()); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\thostKind, _, ok := bedrockHostKind(base.Hostname())\n\t\tif !ok || hostKind != kind {\n\t\t\treturn nil, fmt.Errorf(\"bedrock endpoint host %q does not match endpoint kind %q\", base.Hostname(), kind)\n\t\t}\n\t}\n\treturn base, nil\n}\n\nfunc endpointKindForPath(path string) string {\n\tswitch {\n\tcase strings.HasPrefix(path, \"/bedrock/model/\"):","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/proxy/providers/bedrock/routing.go#L179-L215","documentation":"ResolveUpstreamURL recognizes exactly two Bedrock route shapes: /bedrock/model/... (Runtime) and /bedrock/anthropic/... (Mantle). endpointKindForPath returns \"\" for anything else and the default case rejects it, keeping the proxy fail-closed on unknown routes rather than forwarding arbitrary paths to AWS.","triggerScenarios":"Any request path not starting with /bedrock/model/ or /bedrock/anthropic/ sent to the Bedrock adapter, e.g. /bedrock/, /bedrock/foundation-models, /bedrock/model (no trailing slash + resource), or a client accidentally configured with provider=bedrock for a non-Bedrock path.","commonSituations":"A generic AWS SDK client pointed at the proxy issuing management-plane calls (ListFoundationModels, etc.) which the proxy does not route; misconfigured base path stripping so the /model/ segment is lost; clients using the raw AWS API path format (/model/{modelId}/invoke) without the required /bedrock prefix.","solutions":["Ensure the path starts with /bedrock/model/<modelId>/<action> for Runtime or /bedrock/anthropic/v1/messages for Mantle","If the client sends raw AWS paths (/model/...), configure it to prefix them with /bedrock or fix the mount/base-path in caveman.yaml","Check that no reverse proxy or rewrite rule in front of caveman stripped the /bedrock prefix","Use a provider adapter matching the actual API if this is not Bedrock traffic (e.g. anthropic, openai)"],"exampleFix":"// before\nPOST /model/anthropic.claude-3-5-sonnet/invoke  // missing /bedrock prefix\n// after\nPOST /bedrock/model/anthropic.claude-3-5-sonnet/invoke","handlingStrategy":"validation","validationCode":"if !strings.HasPrefix(path, \"/bedrock/model/\") && !strings.HasPrefix(path, \"/bedrock/anthropic/\") {\n\t// only these two route shapes reach the Bedrock adapter\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build Bedrock proxy URLs starting with /bedrock/","Point AWS management-plane SDK calls directly at AWS, not through the proxy's Bedrock adapter","Document the two route shapes for every client that targets this proxy"],"tags":["bedrock","routing","path-validation","fail-closed"],"backgroundTag":"invalid-url","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"}