{"record":{"id":"62769d7ef73410a9","repo":"micro/go-micro","slug":"failed-to-parse-response-w-62769d","errorCode":null,"errorMessage":"failed to parse response: %w","messagePattern":"failed to parse response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/atlascloud/atlascloud.go","lineNumber":466,"sourceCode":"\t\tretryAfter := time.Duration(0)\n\t\tvar retryErr interface{ RetryAfter() time.Duration }\n\t\tif errors.As(ai.NewHTTPError(httpResp, respBody), &retryErr) {\n\t\t\tretryAfter = retryErr.RetryAfter()\n\t\t}\n\t\treturn nil, nil, &atlascloudAPIError{Status: httpResp.Status, Code: httpResp.StatusCode, Retry: retryAfter, Phase: phase, Summary: atlascloudRequestSummary(req), Body: string(respBody)}\n\t}\n\n\tvar chatResp struct {\n\t\tChoices []struct {\n\t\t\tMessage struct {\n\t\t\t\tContent   string          `json:\"content\"`\n\t\t\t\tToolCalls []atlasToolCall `json:\"tool_calls\"`\n\t\t\t} `json:\"message\"`\n\t\t} `json:\"choices\"`\n\t}\n\n\tif err := json.Unmarshal(respBody, &chatResp); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse response: %w\", err)\n\t}\n\n\tif len(chatResp.Choices) == 0 {\n\t\treturn nil, nil, fmt.Errorf(\"no response from API\")\n\t}\n\n\tchoice := chatResp.Choices[0]\n\tresponse := &ai.Response{\n\t\tReply: choice.Message.Content,\n\t}\n\n\tfor _, tc := range choice.Message.ToolCalls {\n\t\tvar input map[string]any\n\t\tif err := json.Unmarshal([]byte(tc.Function.Arguments), &input); err != nil {\n\t\t\tinput = map[string]any{}\n\t\t}\n\t\tresponse.ToolCalls = append(response.ToolCalls, ai.ToolCall{\n\t\t\tID:    tc.ID,","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/atlascloud/atlascloud.go#L448-L484","documentation":"callAPI wraps the error from json.Unmarshal when the HTTP 200 body cannot be decoded into the expected chat-completion response struct. It means the API returned a 200 whose JSON shape does not match the expected {choices:[{message:{...}}]} schema. The library throws it to surface the decode failure with the underlying *json.UnmarshalTypeError or *json.SyntaxError attached.","triggerScenarios":"json.Unmarshal(respBody, &chatResp) returns an error: the body is empty, truncated, HTML (e.g. a proxy/login page), or field types diverge from the struct (e.g. content returned as an array or null where a string is expected).","commonSituations":"Provider changed its response schema after an API version update; an intermediary (gateway, WAF, captive portal) returned HTML with status 200; response body was read incompletely because io.ReadAll's error was ignored; model returned tool_calls in an unexpected format.","solutions":["Log string(respBody) on this error to see what the API actually returned and compare against the expected chat response schema.","Confirm the API version/model endpoint matches what this provider version expects; pin or update the provider code if AtlasCloud changed its schema.","Check for intermediaries returning HTML (proxy auth pages) by inspecting Content-Type of the response.","Capture the error from io.ReadAll instead of discarding it so truncated bodies are detected before unmarshal."],"exampleFix":"if err := json.Unmarshal(respBody, &chatResp); err != nil {\n    return nil, nil, fmt.Errorf(\"failed to parse response: %w (body: %.200s)\", err, string(respBody))\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isValidChatResponse(b []byte) bool {\n    var probe struct {\n        Choices []json.RawMessage `json:\"choices\"`\n    }\n    return json.Unmarshal(b, &probe) == nil\n}","tryCatchPattern":"resp, err := provider.Generate(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to parse response\") {\n        var uerr *json.UnmarshalTypeError\n        if errors.As(err, &uerr) {\n            log.Printf(\"schema mismatch at %s: %v\", uerr.Field, uerr)\n        }\n    }\n    return err\n}","preventionTips":["Log the raw response body whenever parsing fails to spot schema drift early.","Pin the provider API version in BaseURL where supported.","Check Content-Type of responses to detect HTML from proxies/WAFs.","Keep the provider library updated when the AtlasCloud API changes."],"tags":["json","schema-mismatch","go","atlascloud"],"backgroundTag":"response-schema-validation-failed","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}