alibaba/open-code-review · error
invalid model list for %s: %w
Error message
invalid model list for %s: %w
What it means
The provider-level models field is parsed by parseModelListValue; if the value cannot be parsed into a valid model list, applyProviderField wraps the failure as "invalid model list for <key>: %w" with the full dotted key.
Source
Thrown at cmd/opencodereview/config_cmd.go:644
if err := llm.ValidateProtocol(normalized); err != nil {
return err
}
entry.Protocol = normalized
// Switching away from bedrock leaves aws_region/aws_profile as dead
// config that reads as applied but nothing reads it — clear both, the
// same way the TUI drops url/api_key/auth_header when switching onto
// bedrock (see cpAmbientProtocol in provider_tui.go).
if normalized != llm.ProtocolAnthropicBedrock && (entry.AWSRegion != "" || entry.AWSProfile != "") {
fmt.Fprintf(os.Stderr, "[ocr] WARNING: clearing aws_region/aws_profile on %q: protocol %q does not use the AWS credential chain\n", providerName, normalized)
entry.AWSRegion = ""
entry.AWSProfile = ""
}
case "model":
entry.Model = value
case "models":
models, err := parseModelListValue(value)
if err != nil {
return fmt.Errorf("invalid model list for %s: %w", key, err)
}
entry.Models = models
case "auth_header":
normalized, err := llm.NormalizeAuthHeader(value)
if err != nil {
return err
}
entry.AuthHeader = normalized
case "extra_body":
var m map[string]any
if err := json.Unmarshal([]byte(value), &m); err != nil {
return fmt.Errorf("invalid JSON for %s: %w", key, err)
}
entry.ExtraBody = m
case "extra_headers":
parsed, err := llm.ParseExtraHeaders(value)
if err != nil {
return fmt.Errorf("invalid extra headers for %s: %w", key, err)View on GitHub (pinned to 5cf97d0d15)
Solutions
- Check parseModelListValue's expected format (comma-separated names vs JSON array) and reformat the value
- Provide at least one model name; an empty value produces no valid list
- Quote the value so shell word-splitting doesn't break it: `ocr config set providers.x.models "m1,m2"`
- Set a single default with the `model` field instead if you don't need a list
Example fix
// before ocr config set providers.openai.models "" // after ocr config set providers.openai.models "gpt-4o,gpt-4o-mini"
Defensive patterns
Strategy: validation
Validate before calling
models := strings.Split(value, ",")
for i, m := range models {
models[i] = strings.TrimSpace(m)
}
if len(models) == 0 || (len(models) == 1 && models[0] == "") {
return errors.New("models needs at least one model name")
}
_ = runConfigSet("providers.openai.models", strings.Join(models, ",")) Try / catch
if err := runConfigSet("providers.openai.models", v); err != nil {
if strings.Contains(err.Error(), "invalid model list for") {
fmt.Fprintf(os.Stderr, "%q is not a valid model list; supply at least one model name\n", v)
}
} Prevention
- Quote comma-separated values so the shell doesn't split them
- Never pass an empty string as the list; use the single `model` field for one default
- Trim spaces around each name
- Match the format parseModelListValue expects (comma-separated names) rather than JSON arrays
When it happens
Trigger: `ocr config set providers.<name>.models <value>` (or custom_providers path) with an empty list, malformed separators, or a structure parseModelListValue rejects.
Common situations: Passing comma-separated names where a JSON array is expected (or vice versa); quoting mistakes eating the separators; an empty string from an unset shell variable; switching providers and pasting the wrong list format.
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 retry codes for %s: %w
- invalid %s for %s: %q contains whitespace
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/2d972aa8a9d09f7f.
Report an issue: GitHub.