router-for-me/CLIProxyAPI · error
response JSON does not contain models array
Error message
response JSON does not contain models array
What it means
After successfully parsing the response JSON, countModels requires a top-level `models` array. If the decoded object has no `models` key at all (payload.Models == nil), it returns `response JSON does not contain models array`. The check is intentionally loose (per the code comment): this tool dumps the upstream payload, and strict catalog validation belongs to cmd/validate_codex_models — but a payload without any models array is unusable even for dumping.
Source
Thrown at cmd/fetch_codex_models/main.go:308
q := u.Query()
q.Set("client_version", strings.TrimSpace(clientVersion))
u.RawQuery = q.Encode()
}
return u.String(), nil
}
func countModels(raw []byte) (int, error) {
var payload struct {
Models []json.RawMessage `json:"models"`
}
if err := json.Unmarshal(raw, &payload); err != nil {
return 0, fmt.Errorf("failed to parse response JSON: %w", err)
}
// Keep this check intentionally loose: fetch_codex_models dumps the upstream
// Codex API payload. Strict CPA catalog validation belongs in
// cmd/validate_codex_models and registry.ValidateCodexClientModelsJSON.
if payload.Models == nil {
return 0, fmt.Errorf("response JSON does not contain models array")
}
return len(payload.Models), nil
}
func prettyJSON(raw []byte) ([]byte, error) {
var buf bytes.Buffer
if err := json.Indent(&buf, raw, "", " "); err != nil {
return nil, err
}
buf.WriteByte('\n')
return buf.Bytes(), nil
}
func metaStringValue(m map[string]any, key string) string {
if m == nil {
return ""
}
v, ok := m[key]View on GitHub (pinned to 78f0c4079e)
Solutions
- Dump the top-level keys of the returned JSON to see what the endpoint actually sent instead of models.
- Update the Codex client version used for the request; endpoint shape follows client generation.
- If a gateway rewrites responses, exclude the Codex models URL from rewriting.
- Run cmd/validate_codex_models against known-good data to confirm which side changed.
Defensive patterns
Strategy: validation
Validate before calling
func hasModelsArray(b []byte) bool {
return gjson.GetBytes(b, "models").IsArray()
} Type guard
func isMissingModelsArray(err error) bool {
return err != nil && strings.Contains(err.Error(), "does not contain models array")
} Prevention
- Check for a top-level models array before consuming the payload.
- Keep the Codex client version aligned with the current endpoint shape.
- Use cmd/validate_codex_models for strict catalog validation rather than this dump tool.
When it happens
Trigger: The 2xx JSON response is a valid object but lacks `models`: an error envelope like {"error": ...} returned with 200, an auth redirect payload, an upstream API revision that renamed/removed the field, or a different endpoint answering than expected.
Common situations: Endpoint contract change after Codex client update; gateways that wrap responses in {"data": ...}; tokens that entitle to a different response shape; stale cached responses from a proxy.
Related errors
- models request failed with status %d: %s
- missing access_token and refresh_token
- refresh response did not include access_token
- failed to parse response JSON: %w
- failed to parse token response: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/29c9697fdb8fe497.
Report an issue: GitHub.