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

  1. Set OCR_LLM_URL, OCR_LLM_TOKEN, and OCR_LLM_MODEL in the environment, or
  2. Create ~/.opencodereview/config.json with a complete provider entry (url, api_key, model, protocol), or
  3. Export ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_MODEL if using a Claude-compatible setup
  4. For Bedrock-style ambient auth, configure protocol "anthropic-bedrock" with a valid AWS credential chain
  5. 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

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


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/f7dbd28f4c612fa2. Report an issue: GitHub.