{"record":{"id":"a08aeb3f326163ee","repo":"micro/go-micro","slug":"no-response-from-api-a08aeb","errorCode":null,"errorMessage":"no response from API","messagePattern":"no response from API","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/ollama/ollama.go","lineNumber":278,"sourceCode":"\t\t\tMessage struct {\n\t\t\t\tRole      string `json:\"role\"`\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{\n\t\tReply: choice.Message.Content,\n\t\tUsage: ai.Usage{\n\t\t\tInputTokens:  chatResp.Usage.PromptTokens,\n\t\t\tOutputTokens: chatResp.Usage.CompletionTokens,\n\t\t\tTotalTokens:  chatResp.Usage.TotalTokens,\n\t\t},\n\t}\n\n\tvar rawToolCalls []map[string]any\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}","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/ollama/ollama.go#L260-L296","documentation":"Thrown when the Ollama OpenAI-compatible chat response parses successfully but contains an empty choices array. The provider requires at least one choice to build the ai.Response, so an empty array yields 'no response from API'.","triggerScenarios":"len(chatResp.Choices) == 0 in callOpenAI (called from generateOpenAI) — the endpoint returned 200 with choices omitted or empty, e.g. the model generated nothing, the prompt was rejected silently, or an error payload with a 200 status.","commonSituations":"Model loaded but returned empty completion; using the native /api endpoint path with an OpenAI-style client (different schema); Ollama returning an odd empty result during startup/model loading races.","solutions":["Log the raw response body to check for error or metadata fields accompanying empty choices","Ensure the request targets the /v1/chat/completions OpenAI-compatible path, not the native /api/chat path with a mismatched payload","Retry once — the model may still be loading on first request","Verify the model is fully pulled and functional via `ollama run <model>`"],"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: body=%s\", string(respBody))\n}","handlingStrategy":"retry","validationCode":"if req.Model == \"\" || len(req.Messages) == 0 {\n    return fmt.Errorf(\"model and messages required\")\n}","typeGuard":"func hasChoices(c *chatResponse) bool {\n    return c != nil && len(c.Choices) > 0\n}","tryCatchPattern":"resp, err := provider.Stream(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"no response from API\") {\n        // retry once; model may still be loading\n    }\n    return err\n}","preventionTips":["Warm up the model with a first request before production use","Use the correct /v1/chat/completions path for OpenAI-style payloads","Test the model directly with `ollama run` when empty responses occur","Log full response bodies to detect silent errors with 200 status"],"tags":["empty-response","ollama","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"}