{"record":{"id":"c8659c4142f5a2a4","repo":"JuliusBrussee/caveman","slug":"bedrock-base-url-invalid-w","errorCode":null,"errorMessage":"bedrock base url invalid: %w","messagePattern":"bedrock base url invalid: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/bedrock/routing.go","lineNumber":154,"sourceCode":")\n\n// ResolveUpstreamURL validates the endpoint kind, region, action, and model\n// resource, then resolves one of two explicit Bedrock surfaces:\n//\n//   - Runtime: /bedrock/model/... -> bedrock-runtime.../model/...\n//   - Mantle:  /bedrock/anthropic/v1/messages -> bedrock-mantle.../anthropic/...\n//\n// Mantle stays deployment-opt-in because its IAM service, model coverage,\n// quotas, features, stream wire, and AWS invocation-logging support differ from\n// Runtime. Both surfaces remain provider=bedrock in telemetry.\nfunc (a Adapter) ResolveUpstreamURL(ctx context.Context, req *http.Request, route providers.RouteContext) (*url.URL, error) {\n\tbaseURL := a.BaseURL\n\tif route.BaseURL != \"\" {\n\t\tbaseURL = route.BaseURL\n\t}\n\tbase, err := url.Parse(baseURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"bedrock base url invalid: %w\", err)\n\t}\n\tregion, err := resolveRegion(req, base)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkind := endpointKindForPath(req.URL.Path)\n\tif configuredKind := strings.ToLower(strings.TrimSpace(route.EndpointKind)); configuredKind != \"\" && configuredKind != kind {\n\t\treturn nil, fmt.Errorf(\"bedrock configured endpoint kind %q does not allow request kind %q\", configuredKind, kind)\n\t}\n\tswitch kind {\n\tcase endpointRuntime:\n\t\tif !RegionAllowed(region) {\n\t\t\treturn nil, fmt.Errorf(\"bedrock region %q is not on the allowlist\", region)\n\t\t}\n\t\tmodelID, action := parseModelPath(req.URL.Path)\n\t\tif modelID == \"\" || action == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"bedrock request path %q does not name a model and action\", req.URL.Path)","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/providers/bedrock/routing.go#L136-L172","documentation":"The Bedrock adapter parses its base URL (route.BaseURL if set, else the adapter default) before routing, and a malformed value — one that url.Parse rejects — produces this wrapped parse error. Unlike the base adapter, Bedrock needs a parsed URL early because region and endpoint-kind resolution derive from it (runtime vs mantle paths).","triggerScenarios":"Configuring base_url with invalid URL syntax: unmatched percent-encoding ('%zz'), a control character, malformed port ('https://host:port'), or stray whitespace past trimming.","commonSituations":"Hand-edited YAML with a truncated URL; env interpolation inserting an empty or partial value; a pasted URL containing a literal newline; template engines emitting bad percent-escapes.","solutions":["Fix the base_url value to a well-formed absolute URL, e.g. https://bedrock-runtime.us-east-1.amazonaws.com.","Validate at config load: if _, err := url.Parse(v); err != nil { return fmt.Errorf(\"bad base_url: %w\", err) }.","Inspect the raw config/env for hidden characters (cat -A) after templating."],"exampleFix":"# before\nbase_url: \"https://bedrock-runtime.us-east-1.amazonaws.com:%zz\"\n\n# after\nbase_url: \"https://bedrock-runtime.us-east-1.amazonaws.com\"","handlingStrategy":"validation","validationCode":"base := strings.TrimSpace(route.BaseURL)\nif base == \"\" {\n    base = strings.TrimSpace(adapterBaseURL)\n}\nif _, err := url.Parse(base); err != nil {\n    return fmt.Errorf(\"bedrock base_url %q is not parseable: %w\", base, err)\n}","typeGuard":"func isParseableURL(raw string) bool {\n    _, err := url.Parse(strings.TrimSpace(raw))\n    return err == nil\n}","tryCatchPattern":"if _, err := adapter.ResolveUpstreamURL(ctx, req, route); err != nil {\n    if strings.Contains(err.Error(), \"base url invalid\") {\n        http.Error(w, \"bedrock base_url is malformed; fix provider config\", http.StatusBadGateway)\n        return\n    }\n    http.Error(w, err.Error(), http.StatusBadRequest)\n}","preventionTips":["url.Parse-check every configured base URL at config load.","Use cat -A to spot hidden characters after templating.","Prefer full https URLs with region hostnames for bedrock."],"tags":["go","bedrock","configuration","url-parsing","aws"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}