micro/go-micro · error
failed to parse response: %w
Error message
failed to parse response: %w
What it means
This error wraps a json.Unmarshal failure when decoding the Ollama OpenAI-compatible chat response in callOpenAI. It means the response body could not be parsed into the expected choices struct — commonly because the server returned an error page, plain-text error, or a schema the struct does not match.
Source
Thrown at ai/ollama/ollama.go:275
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"`
} `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]anyView on GitHub (pinned to 24529f1404)
Solutions
- Log respBody and the status code before unmarshalling to see the actual payload
- Verify BaseURL points at the Ollama OpenAI-compatible API (…/v1), not the root or native /api endpoint
- Upgrade Ollama to a version supporting the OpenAI-compatible chat completions endpoint
- Decode into json.RawMessage/map first and validate the shape before struct decoding
Example fix
// before
if err := json.Unmarshal(respBody, &chatResp); err != nil {
return nil, nil, fmt.Errorf("failed to parse response: %w", err)
}
// after
if err := json.Unmarshal(respBody, &chatResp); err != nil {
return nil, nil, fmt.Errorf("failed to parse response: %w: body=%.200s", err, string(respBody))
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify the endpoint returns JSON before calling
resp, err := http.Get(strings.TrimRight(baseURL, "/") + "/v1/models")
if err == nil {
ct := resp.Header.Get("Content-Type")
if !strings.Contains(ct, "application/json") {
return fmt.Errorf("endpoint did not return JSON (content-type %s)", ct)
}
} Type guard
func looksLikeJSON(b []byte) bool {
t := bytes.TrimSpace(b)
return len(t) > 0 && (t[0] == '{' || t[0] == '[')
} Try / catch
resp, err := provider.Generate(ctx, req)
if err != nil {
if strings.Contains(err.Error(), "failed to parse response") {
// inspect raw body: proxy HTML? wrong endpoint? old Ollama?
}
return err
} Prevention
- Point BaseURL at the /v1 OpenAI-compatible path
- Log response bodies on parse errors
- Keep Ollama updated to a version with the OpenAI layer
- Check for reverse proxies injecting HTML error pages
When it happens
Trigger: json.Unmarshal(respBody, &chatResp) fails in callOpenAI (called from generateOpenAI) — non-JSON body (HTML from a proxy), truncated response, or Ollama version whose response shape differs from the struct.
Common situations: Hitting a non-Ollama endpoint (e.g. the base URL points to a web root returning HTML); an old Ollama version predating the OpenAI-compatibility layer; a reverse proxy error page; response body truncated by a proxy timeout.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse response: %w
- failed to parse stream chunk: %w
- failed to parse response: %w
- failed to marshal request: %w
- failed to marshal stream request: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/5264679214e5c4b6.
Report an issue: GitHub.