{"record":{"id":"04d2b8bdecb29e47","repo":"router-for-me/CLIProxyAPI","slug":"parse-home-models-payload-w","errorCode":null,"errorMessage":"parse home models payload: %w","messagePattern":"parse home models payload: %w","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/api/server_routes.go","lineNumber":975,"sourceCode":"func unmarshalHomeModelsTopLevel(raw []byte) (map[string]json.RawMessage, bool) {\n\tif len(raw) == 0 {\n\t\treturn nil, false\n\t}\n\tvar top map[string]json.RawMessage\n\tif errUnmarshal := json.Unmarshal(raw, &top); errUnmarshal != nil {\n\t\treturn nil, false\n\t}\n\treturn top, true\n}\n\nfunc decodeHomeModels(raw []byte) ([]homeModelEntry, error) {\n\tif len(raw) == 0 {\n\t\treturn nil, fmt.Errorf(\"home models payload is empty\")\n\t}\n\n\tvar bySection map[string][]map[string]any\n\tif err := json.Unmarshal(raw, &bySection); err != nil {\n\t\treturn nil, fmt.Errorf(\"parse home models payload: %w\", err)\n\t}\n\tif len(bySection) == 0 {\n\t\treturn nil, fmt.Errorf(\"home models payload has no sections\")\n\t}\n\n\tseen := make(map[string]struct{})\n\tout := make([]homeModelEntry, 0, 256)\n\tfor _, models := range bySection {\n\t\tfor _, model := range models {\n\t\t\tid, _ := model[\"id\"].(string)\n\t\t\tid = strings.TrimSpace(id)\n\t\t\tif id == \"\" {\n\t\t\t\tname, _ := model[\"name\"].(string)\n\t\t\t\tname = strings.TrimSpace(name)\n\t\t\t\tid = strings.TrimPrefix(name, \"models/\")\n\t\t\t}\n\t\t\tif id == \"\" {\n\t\t\t\tcontinue","sourceCodeStart":957,"sourceCodeEnd":993,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/api/server_routes.go#L957-L993","documentation":"decodeHomeModels failed to unmarshal the payload into map[string][]map[string]any — the body is non-empty but is not valid JSON, or is valid JSON of an incompatible shape (e.g. an object, a string, or a top-level array). The %w wraps the encoding/json error identifying the exact offset and reason.","triggerScenarios":"Upstream home models endpoint returned HTML (login page, proxy error page) instead of JSON; partial/truncated response; a different schema version where sections are objects rather than arrays.","commonSituations":"Auth expiry causing a 200-redirect to an HTML login page; corporate proxy injecting an error page; upstream schema migration changing section structure.","solutions":["Log the first few hundred bytes of the raw payload to see what was actually returned","If HTML was returned, fix the authentication/session for the home models fetch","If the schema changed, update decodeHomeModels to match the new section structure","Add a Content-Type: application/json check on the fetch response before decoding"],"exampleFix":"// before\nif err := json.Unmarshal(raw, &bySection); err != nil {\n\treturn nil, fmt.Errorf(\"parse home models payload: %w\", err)\n}\n\n// after\nif err := json.Unmarshal(raw, &bySection); err != nil {\n\treturn nil, fmt.Errorf(\"parse home models payload: %w (body prefix: %.200q)\", err, raw)\n}","handlingStrategy":"validation","validationCode":"if !json.Valid(raw) {\n\treturn fmt.Errorf(\"home models payload is not valid JSON (prefix: %.100q)\", raw)\n}\nentries, err := decodeHomeModels(raw)","typeGuard":null,"tryCatchPattern":"var syntaxErr *json.SyntaxError\nif errors.As(err, &syntaxErr) {\n\t// payload corruption or HTML page — refetch rather than retry decode\n}","preventionTips":["Check the fetch response Content-Type is application/json","Detect HTML login pages before decoding","Pin expected schema and alert on upstream drift"],"tags":["json","models-list","parsing","upstream"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}