micro/go-micro · error

API error (%s): %s

Error message

API error (%s): %s

What it means

Raised when the Ollama server responds with a non-200 status to the OpenAI-compatible chat request. The error includes the HTTP status line and the raw response body so the caller can see the server's error message. This is a server-side rejection, not a transport failure.

Source

Thrown at ai/ollama/ollama.go:250

	apiURL := strings.TrimRight(p.opts.BaseURL, "/") + p.chatPath()
	httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create request: %w", err)
	}
	httpReq.Header.Set("Content-Type", "application/json")
	if p.opts.APIKey != "" {
		httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)
	}

	httpResp, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, nil, fmt.Errorf("API request failed: %w", err)
	}
	defer httpResp.Body.Close()

	respBody, _ := io.ReadAll(httpResp.Body)
	if httpResp.StatusCode != http.StatusOK {
		return nil, nil, fmt.Errorf("API error (%s): %s", httpResp.Status, string(respBody))
	}

	var chatResp struct {
		Usage struct {
			PromptTokens     int `json:"prompt_tokens"`
			CompletionTokens int `json:"completion_tokens"`
			TotalTokens      int `json:"total_tokens"`
		} `json:"usage"`
		Choices []struct {
			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"`

View on GitHub (pinned to 24529f1404)

Solutions

  1. Read the error body in the message — it names the actual problem (model not found, bad request, etc.)
  2. Run `ollama list` / `ollama pull <model>` to ensure the requested model exists locally
  3. Check the request payload: model name, tool definitions, and message roles must be valid for the OpenAI-compatible endpoint
  4. If a proxy/API key is involved, verify the Authorization header and proxy configuration

Example fix

// before
resp, err := provider.Generate(ctx, ai.Request{Model: "llama3.1:latest"})
// after
// if error says 404 model not found:
out, err := exec.Command("ollama", "pull", "llama3.1").CombinedOutput()
// then retry the request
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the model is available before calling
out, err := exec.Command("ollama", "list").Output()
if err != nil || !strings.Contains(string(out), "llama3.1") {
    return fmt.Errorf("model not pulled: run ollama pull <model>")
}

Type guard

func isNotFoundStatus(err error) bool {
    return strings.Contains(err.Error(), "API error (404")
}

Try / catch

resp, err := provider.Generate(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "API error (") {
        // parse status from message; 404 → pull model, 400 → fix payload, 401 → fix auth
    }
    return err
}

Prevention

When it happens

Trigger: httpResp.StatusCode != http.StatusOK in callOpenAI (called from generateOpenAI) — e.g. 404 because the model is not pulled, 400 for a malformed request (bad model name, invalid tool schema), 401/403 when an API key is required but wrong, 500 from an Ollama internal error.

Common situations: Model name not found locally (ollama pull never run) → 404; malformed tools/messages payloads → 400; proxy in front of Ollama requiring auth → 401/403; OOM or internal errors on large prompts → 500.

Related errors


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