JuliusBrussee/caveman · error
compat upstream : base_url is required
Error message
compat upstream %q: base_url is required
What it means
A compat upstream entry was defined but its base_url is empty or whitespace-only. The proxy cannot route OpenAI-compatible requests to an upstream without an endpoint URL, so validateCompat rejects it at load time.
Solutions
- Set base_url to the upstream's full API endpoint, e.g. "https://api.example.com/v1".
- Remove the empty compat upstream entry entirely if it is not used.
- If base_url is injected from env/templating, fix the empty substitution in the pipeline.
Example fix
// before [compat."foo"] // after [compat."foo"] base_url = "https://api.example.com/v1"
Defensive patterns
Strategy: validation
Validate before calling
if strings.TrimSpace(upstream.BaseURL) == "" {
return fmt.Errorf("compat upstream %q: base_url is required", name)
} Prevention
- Use a config schema/template where base_url is a required field for every compat entry.
- Check templating pipelines don't drop empty values silently.
- Validate configs at startup in staging before production.
When it happens
Trigger: Defining a compat upstream section with only a name (e.g. [compat."foo"] with no fields), or setting base_url = "" or base_url = " " in the config file, then calling Load.
Common situations: Scaffolding a new upstream entry and forgetting to fill in base_url; a templating step that omitted empty values; hand-edited TOML/JSON/YAML with the key deleted.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- cave_live_eval_sandbox_profile_missing
- compat upstream : base_url
- compat upstream : forward_headers
- compat upstream
- : MCP ownership journal failed; native config may already…
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/8282055c41923c05.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/internal/config/config.go:458
}
// BedrockBaseURL returns an explicit operator override or derives AWS's standard
// Runtime endpoint from BedrockRegion. Callers never need to paste a raw URL for
// the normal first-party path.
func (c Config) BedrockBaseURL() string {
if configured := c.BaseURL("bedrock", ""); configured != "" {
return configured
}
return fmt.Sprintf("https://bedrock-runtime.%s.amazonaws.com", c.BedrockRegion())
}
func (c Config) validateCompat() error {
for name, upstream := range c.Compat {
if err := openaicompat.ValidateName(name); err != nil {
return fmt.Errorf("compat upstream %q: %w", name, err)
}
if strings.TrimSpace(upstream.BaseURL) == "" {
return fmt.Errorf("compat upstream %q: base_url is required", name)
}
if err := openaicompat.ValidateBaseURL(upstream.BaseURL); err != nil {
return fmt.Errorf("compat upstream %q: base_url: %w", name, err)
}
if err := openaicompat.ValidateForwardHeaders(upstream.ForwardHeaders); err != nil {
return fmt.Errorf("compat upstream %q: forward_headers: %w", name, err)
}
if err := openaicompat.ValidateWireDialect(upstream.WireDialect); err != nil {
return fmt.Errorf("compat upstream %q: %w", name, err)
}
}
return nil
}
// providerEnvKey maps a provider name to the BYOK environment variable that
// holds its API key.
var providerEnvKey = map[string]string{
"anthropic": "ANTHROPIC_API_KEY",View on GitHub (pinned to 3ee70a1026)