{"record":{"id":"e8416d745dc89c43","repo":"JuliusBrussee/caveman","slug":"compat-upstream-q-base-url-w","errorCode":null,"errorMessage":"compat upstream %q: base_url: %w","messagePattern":"compat upstream %q: base_url: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/internal/config/config.go","lineNumber":461,"sourceCode":"// Runtime endpoint from BedrockRegion. Callers never need to paste a raw URL for\n// the normal first-party path.\nfunc (c Config) BedrockBaseURL() string {\n\tif configured := c.BaseURL(\"bedrock\", \"\"); configured != \"\" {\n\t\treturn configured\n\t}\n\treturn fmt.Sprintf(\"https://bedrock-runtime.%s.amazonaws.com\", c.BedrockRegion())\n}\n\nfunc (c Config) validateCompat() error {\n\tfor name, upstream := range c.Compat {\n\t\tif err := openaicompat.ValidateName(name); err != nil {\n\t\t\treturn fmt.Errorf(\"compat upstream %q: %w\", name, err)\n\t\t}\n\t\tif strings.TrimSpace(upstream.BaseURL) == \"\" {\n\t\t\treturn fmt.Errorf(\"compat upstream %q: base_url is required\", name)\n\t\t}\n\t\tif err := openaicompat.ValidateBaseURL(upstream.BaseURL); err != nil {\n\t\t\treturn fmt.Errorf(\"compat upstream %q: base_url: %w\", name, err)\n\t\t}\n\t\tif err := openaicompat.ValidateForwardHeaders(upstream.ForwardHeaders); err != nil {\n\t\t\treturn fmt.Errorf(\"compat upstream %q: forward_headers: %w\", name, err)\n\t\t}\n\t\tif err := openaicompat.ValidateWireDialect(upstream.WireDialect); err != nil {\n\t\t\treturn fmt.Errorf(\"compat upstream %q: %w\", name, err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// providerEnvKey maps a provider name to the BYOK environment variable that\n// holds its API key.\nvar providerEnvKey = map[string]string{\n\t\"anthropic\":         \"ANTHROPIC_API_KEY\",\n\t\"openai\":            \"OPENAI_API_KEY\",\n\t\"gemini\":            \"GEMINI_API_KEY\",\n\t\"azure_openai\":      \"AZURE_OPENAI_API_KEY\",","sourceCodeStart":443,"sourceCodeEnd":479,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/proxy/internal/config/config.go#L443-L479","documentation":"The compat upstream's base_url was non-empty but failed openaicompat.ValidateBaseURL, with the underlying reason wrapped after the \"base_url: \" prefix. The URL must be a well-formed HTTP(S) endpoint suitable for an OpenAI-compatible API base.","triggerScenarios":"Setting base_url to a malformed URL — missing scheme (\"api.example.com/v1\"), unsupported scheme (\"ftp://...\"), garbage like \"localhost port 8080\", or a value that fails the validator's URL rules — then calling Load.","commonSituations":"Omitting \"https://\" when pasting a host; including spaces or trailing junk; using a unix-socket or internal scheme the validator does not accept.","solutions":["Fix base_url to a well-formed absolute URL with an http/https scheme, e.g. \"https://api.example.com/v1\".","Check the wrapped error text for the specific rule violated and correct that aspect (scheme, host, parsing).","Trim whitespace/quotes from the configured value."],"exampleFix":"// before\nbase_url = \"api.example.com/v1\"\n// after\nbase_url = \"https://api.example.com/v1\"","handlingStrategy":"validation","validationCode":"if err := openaicompat.ValidateBaseURL(upstream.BaseURL); err != nil {\n    return fmt.Errorf(\"compat upstream %q base_url invalid: %w\", name, err)\n}\n// or pre-check:\nif u, err := url.Parse(upstream.BaseURL); err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"base_url must be an absolute http(s) URL\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include https:// (or http://) in base_url values.","Copy endpoint URLs directly from provider docs, not by typing them.","Trim whitespace before saving config values."],"tags":["config","compat","url"],"backgroundTag":"invalid-url-format","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"}