alibaba/open-code-review · error
no valid LLM endpoint configured; one of OCR_LLM_URL/OCR_LLM
Error message
no valid LLM endpoint configured; one of OCR_LLM_URL/OCR_LLM_TOKEN/OCR_LLM_MODEL, ~/.opencodereview/config.json, or ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_MODEL must be set
What it means
This is the terminal failure of endpoint resolution: no strategy produced a complete endpoint. A complete endpoint needs a model plus either a URL+token, or AmbientAuth (Bedrock-style, where transport supplies both). The message enumerates every accepted configuration surface so users know all their options.
Source
Thrown at internal/llm/resolver.go:149
{"OCR environment", func() (ResolvedEndpoint, bool, error) { return tryOCREnv(opts.Model) }},
{"Claude Code environment", func() (ResolvedEndpoint, bool, error) { return tryCCEnv(opts.Model) }},
{"Shell rc file", func() (ResolvedEndpoint, bool, error) { return tryShellRC(opts.Model) }},
}
for _, strategy := range strategies {
ep, ok, err := strategy.fn()
if err != nil {
return ResolvedEndpoint{}, fmt.Errorf("resolve %s: %w", strategy.name, err)
}
// An ambient-auth endpoint is complete without a URL or token: the
// transport supplies both. Everything else still needs all three.
complete := ep.Model != "" && (ep.AmbientAuth || (ep.URL != "" && ep.Token != ""))
if ok && complete {
return finalizeResolvedEndpoint(strategy.name, ep, env), nil
}
}
return ResolvedEndpoint{}, fmt.Errorf("no valid LLM endpoint configured; one of OCR_LLM_URL/OCR_LLM_TOKEN/OCR_LLM_MODEL, ~/.opencodereview/config.json, or ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_MODEL must be set")
}
// envOverrides holds the global OCR_LLM_* overrides that apply to whichever
// strategy resolves the endpoint. Parsed once, up front — see the call site in
// ResolveEndpointWithOptions for why the timing matters.
type envOverrides struct {
timeout time.Duration
hasTimeout bool
headers map[string]string
}
func parseEnvOverrides() (envOverrides, error) {
var env envOverrides
var err error
env.timeout, env.hasTimeout, err = parseTimeoutEnv()
if err != nil {
return envOverrides{}, err
}View on GitHub (pinned to 5cf97d0d15)
Solutions
- Set OCR_LLM_URL, OCR_LLM_TOKEN, and OCR_LLM_MODEL in the environment, or
- Create ~/.opencodereview/config.json with a complete provider entry (url, api_key, model, protocol), or
- Export ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_MODEL if using a Claude-compatible setup
- For Bedrock-style ambient auth, configure protocol "anthropic-bedrock" with a valid AWS credential chain
- In CI, export the variables in the job environment rather than relying on interactive shell rc files
Example fix
// before $ ocr review ... # no env, no config // after $ export OCR_LLM_URL=https://api.anthropic.com OCR_LLM_TOKEN=sk-... OCR_LLM_MODEL=claude-sonnet-4 $ ocr review ...
Defensive patterns
Strategy: validation
Validate before calling
func hasLLMConfig() error {
if os.Getenv("OCR_LLM_URL") != "" && os.Getenv("OCR_LLM_TOKEN") != "" && os.Getenv("OCR_LLM_MODEL") != "" {
return nil
}
if _, err := os.Stat(filepath.HomeDir() + "/.opencodereview/config.json"); err == nil {
return nil
}
if os.Getenv("ANTHROPIC_BASE_URL") != "" && os.Getenv("ANTHROPIC_AUTH_TOKEN") != "" {
return nil
}
return errors.New("no LLM endpoint configured; set OCR_LLM_URL/TOKEN/MODEL or create ~/.opencodereview/config.json")
} Try / catch
ep, err := llm.ResolveEndpoint(path)
if err != nil && strings.Contains(err.Error(), "no valid LLM endpoint configured") {
printSetupInstructions(); os.Exit(2)
} Prevention
- Export the full trio OCR_LLM_URL/OCR_LLM_TOKEN/OCR_LLM_MODEL, not a subset
- In CI, set env vars in the job environment (rc files rarely load there)
- Keep provider entries complete: url, api_key, model, protocol
- For Bedrock, rely on a valid AWS credential chain instead of URL/token
When it happens
Trigger: ResolveEndpointWithOptions with none of OCR_LLM_URL/OCR_LLM_TOKEN/OCR_LLM_MODEL set, no usable ~/.opencodereview/config.json, and no ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_MODEL exported — or sets that exist but are incomplete (e.g. URL without token, or no model anywhere).
Common situations: Running ocr on a fresh machine/CI container with no LLM env vars; partially set variables (OCR_LLM_URL but no OCR_LLM_TOKEN); config file exists but its provider entry is incomplete so it is judged not complete; shell rc sets ANTHROPIC_* only in interactive shells, not in CI.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- resolve OCR config file: %w
- resolve OCR config file: provider %q is not configured in %s
- resolve %s: %w
- load config: %w
- unset supports provider, max_tokens, effort, custom_provider
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/f7dbd28f4c612fa2.
Report an issue: GitHub.