{"record":{"id":"29c9697fdb8fe497","repo":"router-for-me/CLIProxyAPI","slug":"response-json-does-not-contain-models-array","errorCode":null,"errorMessage":"response JSON does not contain models array","messagePattern":"response JSON does not contain models array","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/fetch_codex_models/main.go","lineNumber":308,"sourceCode":"\t\tq := u.Query()\n\t\tq.Set(\"client_version\", strings.TrimSpace(clientVersion))\n\t\tu.RawQuery = q.Encode()\n\t}\n\treturn u.String(), nil\n}\n\nfunc countModels(raw []byte) (int, error) {\n\tvar payload struct {\n\t\tModels []json.RawMessage `json:\"models\"`\n\t}\n\tif err := json.Unmarshal(raw, &payload); err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to parse response JSON: %w\", err)\n\t}\n\t// Keep this check intentionally loose: fetch_codex_models dumps the upstream\n\t// Codex API payload. Strict CPA catalog validation belongs in\n\t// cmd/validate_codex_models and registry.ValidateCodexClientModelsJSON.\n\tif payload.Models == nil {\n\t\treturn 0, fmt.Errorf(\"response JSON does not contain models array\")\n\t}\n\treturn len(payload.Models), nil\n}\n\nfunc prettyJSON(raw []byte) ([]byte, error) {\n\tvar buf bytes.Buffer\n\tif err := json.Indent(&buf, raw, \"\", \"  \"); err != nil {\n\t\treturn nil, err\n\t}\n\tbuf.WriteByte('\\n')\n\treturn buf.Bytes(), nil\n}\n\nfunc metaStringValue(m map[string]any, key string) string {\n\tif m == nil {\n\t\treturn \"\"\n\t}\n\tv, ok := m[key]","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/cmd/fetch_codex_models/main.go#L290-L326","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func hasModelsArray(b []byte) bool {\n    return gjson.GetBytes(b, \"models\").IsArray()\n}","typeGuard":"func isMissingModelsArray(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"does not contain models array\")\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["codex","json","upstream-api","cli"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}