{"record":{"id":"e4c2384cf22e77ef","repo":"JuliusBrussee/caveman","slug":"compat-upstream-name-q-must-match-a-z0-9-a-z0-9","errorCode":null,"errorMessage":"compat upstream name %q must match [a-z0-9][a-z0-9._-]{0,63}","messagePattern":"compat upstream name %q must match \\[a-z0-9\\]\\[a-z0-9\\._-\\](.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/providers/openaicompat/openaicompat.go","lineNumber":247,"sourceCode":"\t}\n\tbaseURL = strings.TrimSpace(baseURL)\n\tif err := ValidateBaseURL(baseURL); err != nil {\n\t\treturn nil, fmt.Errorf(\"compat upstream %q base_url: %w\", name, err)\n\t}\n\tprefix := \"/compat/\" + name\n\treturn namedAdapter{\n\t\tBase: providers.Base{\n\t\t\tProvider: \"openai_compatible\",\n\t\t\tBaseURL:  baseURL,\n\t\t\tRoutes:   []string{prefix + \"/\"},\n\t\t},\n\t\tprefix: prefix,\n\t}, nil\n}\n\nfunc ValidateName(name string) error {\n\tif !validName.MatchString(name) {\n\t\treturn fmt.Errorf(\"compat upstream name %q must match [a-z0-9][a-z0-9._-]{0,63}\", name)\n\t}\n\tswitch name {\n\tcase \"stub\", \"openai-compatible\":\n\t\treturn fmt.Errorf(\"compat upstream name %q is reserved\", name)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc ValidateBaseURL(raw string) error {\n\t_, err := parseBaseURL(raw, \"compat\")\n\treturn err\n}\n\n// ResolveUpstreamURL intentionally ignores RouteContext.BaseURL. Named mounts\n// are configured as independent static upstreams (`compat:` in standalone or\n// CAVE_COMPAT_UPSTREAMS in managed mode); applying the generic project\n// openai_compatible override here would collapse every named route onto one","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/proxy/providers/openaicompat/openaicompat.go#L229-L265","documentation":"ValidateName enforces the compat upstream naming rule: names must match [a-z0-9][a-z0-9._-]{0,63}. Names with uppercase, spaces, leading separators, or excessive length fail this regex guard before reservation checks.","triggerScenarios":"Thrown at proxy/providers/openaicompat/openaicompat.go:204 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rename the upstream using lowercase letters, digits, and . _ - only, starting with a letter or digit, max 64 chars","Check for uppercase or spaces introduced by tooling"],"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"}