{"record":{"id":"310d13d6ceaf1fa0","repo":"github/copilot-sdk","slug":"failed-to-unmarshal-models-response-w","errorCode":null,"errorMessage":"failed to unmarshal models response: %w","messagePattern":"failed to unmarshal models response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/client.go","lineNumber":1946,"sourceCode":"\t\t// Use custom handler instead of CLI RPC\n\t\tvar err error\n\t\tmodels, err = c.onListModels(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tif c.client == nil {\n\t\t\treturn nil, fmt.Errorf(\"client not connected\")\n\t\t}\n\t\t// Cache miss - fetch from backend while holding lock\n\t\tresult, err := c.client.Request(ctx, \"models.list\", listModelsRequest{})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar response listModelsResponse\n\t\tif err := json.Unmarshal(result, &response); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to unmarshal models response: %w\", err)\n\t\t}\n\t\tmodels = response.Models\n\t}\n\n\t// Update cache before releasing lock (copy to prevent external mutation)\n\tcache := make([]ModelInfo, len(models))\n\tcopy(cache, models)\n\tc.modelsCache = cache\n\n\t// Return a copy to prevent cache mutation\n\tresult := make([]ModelInfo, len(models))\n\tcopy(result, models)\n\treturn result, nil\n}\n\n// minProtocolVersion is the minimum protocol version this SDK can communicate with.\nconst minProtocolVersion = 3\nconst runtimeShutdownTimeout = 10 * time.Second","sourceCodeStart":1928,"sourceCodeEnd":1964,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/client.go#L1928-L1964","documentation":"ListModels wraps a json.Unmarshal failure of the raw models.list RPC result with this error. The backend returned JSON that does not fit the expected listModelsResponse shape. It almost always indicates a server/SDK protocol or payload mismatch rather than a caller mistake.","triggerScenarios":"The models.list RPC succeeds at the transport level but its result bytes cannot be decoded into listModelsResponse — e.g. server returns an object with different field names/types, a bare array, or truncated/non-JSON output.","commonSituations":"Mixing an older CLI binary with a newer SDK (or vice versa), a proxy injecting HTML error pages, or a server bug changing the models payload schema.","solutions":["Verify the CLI backend and SDK versions match; upgrade the SDK or server so the models response schema aligns.","Log the raw result payload (before unmarshal) to see the actual JSON shape returned.","Check for proxies/wrappers altering the response body between server and SDK.","Update server to a version whose models.list response includes the expected fields (e.g. models array of ModelInfo)."],"exampleFix":"// before\nvar response listModelsResponse\nif err := json.Unmarshal(result, &response); err != nil {\n    return nil, fmt.Errorf(\"failed to unmarshal models response: %w\", err)\n}\n\n// after (debug the raw payload)\nif err := json.Unmarshal(result, &response); err != nil {\n    return nil, fmt.Errorf(\"failed to unmarshal models response: %w (payload: %s)\", err, truncate(result, 512))\n}","handlingStrategy":"validation","validationCode":"// verify version compatibility before RPC\nif client.GetNegotiatedProtocolVersion() == 0 {\n    return errors.New(\"handshake incomplete; payload schema may differ\")\n}","typeGuard":null,"tryCatchPattern":"models, err := client.ListModels(ctx)\nvar umErr *json.UnmarshalTypeError\nif errors.As(err, &umErr) || strings.Contains(err.Error(), \"failed to unmarshal models response\") {\n    // log payload + versions, surface as protocol mismatch\n    return fmt.Errorf(\"protocol/schema mismatch: %w\", err)\n}","preventionTips":["Keep SDK and CLI/server versions aligned.","Pin dependency versions in go.mod and upgrade together with the backend.","Log raw RPC payloads on decode failure for diagnosis.","Check for middleware/proxies rewriting response bodies."],"tags":["go","json","unmarshal","protocol-mismatch"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}