JuliusBrussee/caveman · error

compat upstream %q: base_url is required

Error message

compat upstream %q: base_url is required

What it means

validateCompat requires every compat upstream entry to carry a non-blank base_url. Named compat mounts are independent static upstreams, so unlike first-party providers there is no default URL to fall back on — an empty or whitespace-only base_url cannot be routed and fails config load.

Source

Thrown at proxy/internal/config/config.go:248

}

// 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)
		}
	}
	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",
	"openai":            "OPENAI_API_KEY",
	"gemini":            "GEMINI_API_KEY",
	"azure_openai":      "AZURE_OPENAI_API_KEY",
	"openai_compatible": "OPENAI_COMPAT_API_KEY",
}

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Add the provider's API base URL, e.g. base_url: https://openrouter.ai/api/v1
  2. Verify YAML indentation so base_url sits under the correct compat name
  3. Remove the compat entry entirely if the upstream is not actually used

Example fix

# before
compat:
  openrouter: {}      # Error[1063]: base_url is required

# after
compat:
  openrouter:
    base_url: https://openrouter.ai/api/v1
Defensive patterns

Strategy: validation

Validate before calling

for name, up := range cfg.Compat {
    if strings.TrimSpace(up.BaseURL) == "" {
        return fmt.Errorf("compat %q: base_url missing — add it before launch", name)
    }
}

Prevention

When it happens

Trigger: compat entry with base_url omitted, set to "", or set to " " (whitespace) in caveman.yaml; or the corresponding env/structured config field never populated when building Config programmatically.

Common situations: Copy-pasting a compat example block but deleting the URL; intending to set the URL later via env and forgetting; YAML indentation putting base_url under the wrong key so it is never read.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/8282055c41923c05. Report an issue: GitHub.