{"record":{"id":"b90a1c55041d511d","repo":"JuliusBrussee/caveman","slug":"provider-q-upstream-url-must-not-include-userinfo","errorCode":null,"errorMessage":"provider %q upstream URL must not include userinfo","messagePattern":"provider %q upstream URL must not include userinfo","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/openaicompat/openaicompat.go","lineNumber":351,"sourceCode":"\treturn nil\n}\n\nfunc parseBaseURL(raw, provider string) (*url.URL, error) {\n\tif strings.TrimSpace(raw) == \"\" {\n\t\treturn nil, fmt.Errorf(\"provider %q has no configured upstream URL\", provider)\n\t}\n\tu, err := url.Parse(strings.TrimSpace(raw))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif u.Scheme != \"http\" && u.Scheme != \"https\" {\n\t\treturn nil, fmt.Errorf(\"provider %q upstream URL scheme %q is not allowed\", provider, u.Scheme)\n\t}\n\tif !u.IsAbs() || u.Host == \"\" || u.Hostname() == \"\" {\n\t\treturn nil, fmt.Errorf(\"provider %q upstream URL must be an absolute URL with a host\", provider)\n\t}\n\tif u.User != nil {\n\t\treturn nil, fmt.Errorf(\"provider %q upstream URL must not include userinfo\", provider)\n\t}\n\tif u.Fragment != \"\" {\n\t\treturn nil, fmt.Errorf(\"provider %q upstream URL must not include a fragment\", provider)\n\t}\n\tif err := validatePathComponents(u.Path, u.RawPath); err != nil {\n\t\treturn nil, fmt.Errorf(\"provider %q upstream URL path rejected: %w\", provider, err)\n\t}\n\treturn u, nil\n}\n","sourceCodeStart":333,"sourceCodeEnd":361,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/proxy/providers/openaicompat/openaicompat.go#L333-L361","documentation":"parseBaseURL rejects upstream URLs embedding credentials (user:pass@host). Credentials in the URL are a security hazard and the proxy authenticates via configured API keys instead.","triggerScenarios":"Thrown at proxy/providers/openaicompat/openaicompat.go:308 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Move credentials out of the URL into the gateway's credential configuration/headers","Regenerate any credentials that were embedded in the URL"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}