{"record":{"id":"1252893d042543ba","repo":"micro/go-micro","slug":"no-response-from-api-125289","errorCode":null,"errorMessage":"no response from API","messagePattern":"no response from API","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/mistral/mistral.go","lineNumber":203,"sourceCode":"\t\tChoices []struct {\n\t\t\tMessage struct {\n\t\t\t\tContent   string `json:\"content\"`\n\t\t\t\tToolCalls []struct {\n\t\t\t\t\tID       string `json:\"id\"`\n\t\t\t\t\tFunction struct {\n\t\t\t\t\t\tName      string `json:\"name\"`\n\t\t\t\t\t\tArguments string `json:\"arguments\"`\n\t\t\t\t\t} `json:\"function\"`\n\t\t\t\t} `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\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{Reply: choice.Message.Content}\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,\n\t\t\tName:  tc.Function.Name,\n\t\t\tInput: input,\n\t\t})\n\t}\n\n\trawMessage := map[string]any{","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/mistral/mistral.go#L185-L221","documentation":"Thrown after a successful JSON parse when the Mistral chat completion response contains zero choices. The library guarantees at least one choice to return a Reply, so an empty choices array is treated as 'no response from API'.","triggerScenarios":"len(chatResp.Choices) == 0 in callAPI — the API responded 200 with an empty choices array, e.g. the prompt was filtered, the model produced no content, or an error payload still returned HTTP 200 with choices omitted.","commonSituations":"Content-filtered prompts; a model name that returns an odd empty completion; API returning {\"choices\":[]} during partial outages; error responses that happen to parse but carry no choices.","solutions":["Log the full response body when choices is empty to inspect any error/metadata fields","Verify the model name and prompt are valid for the Mistral API","Add an error/message field to the response struct and surface it instead of the generic message","Retry the request once; transient empty responses are often intermittent"],"exampleFix":"// before\nif len(chatResp.Choices) == 0 {\n    return nil, nil, fmt.Errorf(\"no response from API\")\n}\n// after\nif len(chatResp.Choices) == 0 {\n    return nil, nil, fmt.Errorf(\"no response from API (status %s): %s\", httpResp.Status, string(respBody))\n}","handlingStrategy":"retry","validationCode":"if req.Model == \"\" {\n    return fmt.Errorf(\"model name is required\")\n}","typeGuard":"func hasChoices(c *chatCompletionResponse) bool {\n    return c != nil && len(c.Choices) > 0\n}","tryCatchPattern":"resp, err := provider.Generate(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"no response from API\") {\n        // retry once with backoff, or surface prompt/model issue to user\n    }\n    return err\n}","preventionTips":["Retry transient empty responses with backoff","Validate model names against the provider's model list","Log the full response body when choices are empty","Check content-filter behavior of your prompts"],"tags":["empty-response","mistral","api"],"backgroundTag":"empty-api-response","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}