micro/go-micro · error
failed to parse response: %w
Error message
failed to parse response: %w
What it means
The library received a 2xx response body but json.Unmarshal could not decode it into the expected chatCompletion response struct. This means the payload was not valid JSON or did not match the expected schema (e.g. choices was an object instead of an array).
Source
Thrown at ai/openai/openai.go:349
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
} `json:"usage"`
Choices []struct {
Message struct {
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},
}
// Extract tool calls
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
- Print/log respBody on this error to see what the server actually returned
- Confirm BaseURL points at an OpenAI-compatible endpoint (path /v1/chat/completions) and not a UI page
- Disable/fix proxies or gateways that inject HTML into responses
- If using a compatible-but-different provider, check its response schema against the library's struct
Example fix
// before apiURL := cfg.OpenAIBaseURL // accidentally https://internal-portal/login // after apiURL := "https://api.openai.com" // real OpenAI-compatible API host
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(cfg.BaseURL)
if err != nil || !strings.HasSuffix(u.Path, "/v1") && u.Path != "" {
// ensure it points at an OpenAI-compatible API root, not a web UI
}
// sanity ping
resp, err := http.Get(cfg.BaseURL + "/v1/models")
ct := resp.Header.Get("Content-Type")
if !strings.Contains(ct, "application/json") {
return fmt.Errorf("endpoint does not return JSON (Content-Type: %s)", ct)
} Try / catch
resp, err := provider.Generate(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed to parse response") {
log.Printf("non-JSON payload from endpoint; check BaseURL/proxy: %v", err)
return err
} Prevention
- Point BaseURL only at OpenAI-compatible JSON API roots
- Disable intercepting proxies that inject HTML into 200 responses
- Verify compatible providers against the OpenAI chat schema
- Log raw bodies on parse failures to speed diagnosis
When it happens
Trigger: callAPI got httpResp.StatusCode == 200 but respBody is not JSON or has unexpected shape: an HTML error/login page from a misconfigured proxy, a truncated body, or an OpenAI-compatible server returning a different schema.
Common situations: Pointing BaseURL at a non-OpenAI service or gateway that returns HTML on success, a gateway stripping/chunk-encoding the body incorrectly, using an OpenAI-compatible provider (e.g. self-hosted) whose response schema diverges.
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 submit response: %w
- failed to marshal stream request: %w
- failed to parse stream chunk: %w
- failed to marshal request: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/6b1902c8ed50bd59.
Report an issue: GitHub.