alibaba/open-code-review · error
custom provider %q requires a url field for protocol %q
Error message
custom provider %q requires a url field for protocol %q
What it means
The resolver builds an endpoint for a custom (non-preset) provider entry. Every protocol except anthropic-bedrock names a concrete HTTP endpoint, so a custom provider entry must carry a `url` field; bedrock is exempt because the AWS region determines the host. This error means a custom provider entry declared a valid, non-bedrock protocol but left `url` empty.
Source
Thrown at internal/llm/resolver.go:460
return ResolvedEndpoint{}, false, fmt.Errorf("provider %q: %w", cfg.Provider, err)
}
protocol = normalized
}
} else {
// Custom provider: protocol is always required; model can come from
// cfg.Model. url is required for every protocol that names an HTTP
// endpoint, which is all of them except bedrock — there the region
// decides the host, so demanding a url would mean storing a value the
// client never reads.
if entry.Protocol == "" {
return ResolvedEndpoint{}, false, fmt.Errorf("custom provider %q requires a protocol field", cfg.Provider)
}
normalized := NormalizeProtocol(entry.Protocol)
if err := ValidateProtocol(normalized); err != nil {
return ResolvedEndpoint{}, false, fmt.Errorf("custom provider %q: %w", cfg.Provider, err)
}
if normalized != ProtocolAnthropicBedrock && entry.URL == "" {
return ResolvedEndpoint{}, false, fmt.Errorf("custom provider %q requires a url field for protocol %q", cfg.Provider, normalized)
}
url = entry.URL
protocol = normalized
}
// Ambient auth follows the protocol actually in force, which is why this is
// resolved after the override above rather than read off the preset. A preset
// declares ambient auth (AmbientAuth), but an entry may override the preset's
// protocol: a bedrock preset switched to "openai" speaks a protocol with no
// SigV4 signing and needs a token like anything else. Conversely an entry
// that selects the bedrock protocol explicitly signs its requests whatever
// the preset says.
ambientAuth := protocol == ProtocolAnthropicBedrock ||
(isPreset && preset.AmbientAuth && entry.Protocol == "")
// No credential at all is an error, and it is reported before api_key_cmd
// runs: only the command's *execution* is deferred, not the emptiness check.
// An ambient-auth provider is the exception — it has no key to configure,View on GitHub (pinned to 5cf97d0d15)
Solutions
- Add a `url` field to the provider entry, e.g. url = "https://api.example.com/v1"
- If the provider really is AWS Bedrock, set protocol = "anthropic-bedrock" (url is then not required; configure region instead)
- Check the key spelling in the config — the url must be inside the same provider entry block
Example fix
// before (config.toml) [providers.my-llm] protocol = "openai" model = "llama3" // after [providers.my-llm] protocol = "openai" url = "http://localhost:8000/v1" model = "llama3"
Defensive patterns
Strategy: validation
Validate before calling
// Go: check a custom provider entry before resolution
func validateCustomProvider(name, protocol, url string) error {
if protocol == "" {
return fmt.Errorf("provider %q: missing protocol", name)
}
if strings.EqualFold(protocol, "anthropic-bedrock") {
return nil // url not required for bedrock
}
if url == "" {
return fmt.Errorf("provider %q: protocol %q requires url", name, protocol)
}
return nil
} Type guard
func hasURLForProtocol(protocol, url string) bool {
return url != "" || strings.EqualFold(protocol, "anthropic-bedrock")
} Try / catch
ep, ok, err := resolver.TryProviderConfig(cfg, override)
if err != nil {
if strings.Contains(err.Error(), "requires a url field") {
fmt.Fprintf(os.Stderr, "config error: add url for provider: %v\n", err)
os.Exit(2)
}
return err
} Prevention
- Always pair a custom provider's protocol with a url in the same entry block
- Never copy bedrock entries (which omit url) as templates for HTTP providers
- Validate the ocr config with a dry run before scripting it in CI
When it happens
Trigger: A [providers] entry without a preset (custom provider) sets `protocol` (e.g. "openai" or "anthropic") but omits `url`, and `ocr review` (via tryOCRConfig -> tryProviderConfig) resolves the endpoint.
Common situations: Adding a new custom/self-hosted provider (vLLM, Ollama, OpenRouter) and forgetting the url; copying an existing bedrock entry (which legitimately has no url) and changing only the protocol; typo-ing the url key so the entry field parses as empty.
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
- invalid max_tokens %q: must be a positive integer
- unknown config key: %s Supported keys: %s Provider fields: a
- invalid URL for %s: %w
- invalid model list for %s: %w
- invalid retry codes for %s: %w
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/773a7c6c6698960b.
Report an issue: GitHub.