micro/go-micro · error

no response from API

Error message

no response from API

What it means

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'.

Source

Thrown at ai/ollama/ollama.go:278

			Message struct {
				Role      string `json:"role"`
				Content   string `json:"content"`
				ToolCalls []struct {
					ID       string `json:"id"`
					Function struct {
						Name      string `json:"name"`
						Arguments string `json:"arguments"`
					} `json:"function"`
				} `json:"tool_calls"`
			} `json:"message"`
		} `json:"choices"`
	}

	if err := json.Unmarshal(respBody, &chatResp); err != nil {
		return nil, nil, fmt.Errorf("failed to parse response: %w", err)
	}
	if len(chatResp.Choices) == 0 {
		return nil, nil, fmt.Errorf("no response from API")
	}

	choice := chatResp.Choices[0]
	response := &ai.Response{
		Reply: choice.Message.Content,
		Usage: ai.Usage{
			InputTokens:  chatResp.Usage.PromptTokens,
			OutputTokens: chatResp.Usage.CompletionTokens,
			TotalTokens:  chatResp.Usage.TotalTokens,
		},
	}

	var rawToolCalls []map[string]any
	for _, tc := range choice.Message.ToolCalls {
		var input map[string]any
		if err := json.Unmarshal([]byte(tc.Function.Arguments), &input); err != nil {
			input = map[string]any{}
		}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Log the raw response body to check for error or metadata fields accompanying empty choices
  2. Ensure the request targets the /v1/chat/completions OpenAI-compatible path, not the native /api/chat path with a mismatched payload
  3. Retry once — the model may still be loading on first request
  4. Verify the model is fully pulled and functional via `ollama run <model>`

Example fix

// before
if len(chatResp.Choices) == 0 {
    return nil, nil, fmt.Errorf("no response from API")
}
// after
if len(chatResp.Choices) == 0 {
    return nil, nil, fmt.Errorf("no response from API: body=%s", string(respBody))
}
Defensive patterns

Strategy: retry

Validate before calling

if req.Model == "" || len(req.Messages) == 0 {
    return fmt.Errorf("model and messages required")
}

Type guard

func hasChoices(c *chatResponse) bool {
    return c != nil && len(c.Choices) > 0
}

Try / catch

resp, err := provider.Stream(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "no response from API") {
        // retry once; model may still be loading
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "empty response", "returned no data", "empty embeddings": what HTTP 200-with-empty-body errors mean across libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/a08aeb3f326163ee. Report an issue: GitHub.