JuliusBrussee/caveman · error
bedrock base url invalid
Error message
bedrock base url invalid: %w
What it means
The Bedrock adapter parses its configured base URL (adapter BaseURL or route.BaseURL) with url.Parse before routing and signing. This error wraps the underlying parse failure — the configured endpoint is not a valid URL at all, so no upstream can be resolved.
Solutions
- Fix the configured base URL so it is a valid absolute https:// URL (no stray characters, quotes, or bad percent-escapes).
- Check route.BaseURL in caveman.yaml first (it overrides the adapter default), then the adapter-level BaseURL.
- Log/print the exact string being parsed — url.Parse errors usually point at the offending component.
Example fix
// before base_url: https://bedrock-runtime.us-east-1.amazonaws.com/%zz // after base_url: https://bedrock-runtime.us-east-1.amazonaws.com
Defensive patterns
Strategy: validation
Validate before calling
base, err := url.Parse(cfg.BaseURL)
if err != nil {
return fmt.Errorf("invalid bedrock base_url %q: %w", cfg.BaseURL, err)
}
if base.Scheme != "https" || base.Host == "" {
return fmt.Errorf("bedrock base_url %q must be an absolute https URL", cfg.BaseURL)
} Try / catch
// Go
if _, err := adapter.ResolveUpstreamURL(ctx, req, route); err != nil {
var uerr *url.Error
if errors.As(err, &uerr) && strings.Contains(err.Error(), "base url invalid") {
// fail fast: fix configuration, do not retry
return fmt.Errorf("configuration error: %w", err)
}
return err
} Prevention
- Validate base_url at config-load time, not at request time.
- Avoid templating URLs by string interpolation; escape or validate expansions.
- Strip quotes/whitespace when pasting endpoints into caveman.yaml.
When it happens
Trigger: A route or adapter configured with a base URL that url.Parse rejects — e.g. containing control characters, an invalid scheme like "hxxp://", or a malformed percent-escape such as https://bedrock-runtime.us-east-1.amazonaws.com/%zz.
Common situations: Typo in caveman.yaml route base_url; pasting an endpoint with stray whitespace or quotes; a templated/interpolated URL where a variable expanded to something containing "{" "}" or spaces.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- bedrock configured endpoint kind
- bedrock region is not on the allowlist
- ErrSigV4Configuration
- AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be set…
- awscreds: build sts request
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/c8659c4142f5a2a4.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/providers/bedrock/routing.go:154
)
// ResolveUpstreamURL validates the endpoint kind, region, action, and model
// resource, then resolves one of two explicit Bedrock surfaces:
//
// - Runtime: /bedrock/model/... -> bedrock-runtime.../model/...
// - Mantle: /bedrock/anthropic/v1/messages -> bedrock-mantle.../anthropic/...
//
// Mantle stays deployment-opt-in because its IAM service, model coverage,
// quotas, features, stream wire, and AWS invocation-logging support differ from
// Runtime. Both surfaces remain provider=bedrock in telemetry.
func (a Adapter) ResolveUpstreamURL(ctx context.Context, req *http.Request, route providers.RouteContext) (*url.URL, error) {
baseURL := a.BaseURL
if route.BaseURL != "" {
baseURL = route.BaseURL
}
base, err := url.Parse(baseURL)
if err != nil {
return nil, fmt.Errorf("bedrock base url invalid: %w", err)
}
region, err := resolveRegion(req, base)
if err != nil {
return nil, err
}
kind := endpointKindForPath(req.URL.Path)
if configuredKind := strings.ToLower(strings.TrimSpace(route.EndpointKind)); configuredKind != "" && configuredKind != kind {
return nil, fmt.Errorf("bedrock configured endpoint kind %q does not allow request kind %q", configuredKind, kind)
}
switch kind {
case endpointRuntime:
if !RegionAllowed(region) {
return nil, fmt.Errorf("bedrock region %q is not on the allowlist", region)
}
modelID, action := parseModelPath(req.URL.Path)
if modelID == "" || action == "" {
return nil, fmt.Errorf("bedrock request path %q does not name a model and action", req.URL.Path)View on GitHub (pinned to 3ee70a1026)