micro/go-micro · error
failed to parse stream chunk: %w
Error message
failed to parse stream chunk: %w
What it means
Recv received an SSE data payload from the Gemini stream and json.Unmarshal failed to decode it into the chunk struct. This indicates the stream delivered data that does not match the expected Gemini streaming response schema — an unexpected payload shape, truncation, or a non-Gemini endpoint behind BaseURL.
Source
Thrown at ai/gemini/gemini.go:246
Code int `json:"code"`
Message string `json:"message"`
Status string `json:"status"`
} `json:"error"`
Candidates []struct {
Content struct {
Parts []struct {
Text string `json:"text"`
} `json:"parts"`
} `json:"content"`
} `json:"candidates"`
UsageMetadata *struct {
PromptTokenCount int `json:"promptTokenCount"`
CandidatesTokenCount int `json:"candidatesTokenCount"`
TotalTokenCount int `json:"totalTokenCount"`
} `json:"usageMetadata"`
}
if err := json.Unmarshal([]byte(data), &chunk); err != nil {
return nil, fmt.Errorf("failed to parse stream chunk: %w", err)
}
if chunk.Error != nil {
return nil, fmt.Errorf("gemini stream error (%s): %s", chunk.Error.Status, chunk.Error.Message)
}
for _, candidate := range chunk.Candidates {
var parts []string
for _, part := range candidate.Content.Parts {
if part.Text != "" {
parts = append(parts, part.Text)
}
}
if len(parts) > 0 {
return &ai.Response{Reply: strings.Join(parts, "")}, nil
}
}
if chunk.UsageMetadata != nil {
return &ai.Response{Usage: ai.Usage{
InputTokens: chunk.UsageMetadata.PromptTokenCount,View on GitHub (pinned to 24529f1404)
Solutions
- Log the raw 'data' payload when this error occurs to see what the endpoint actually sent.
- Verify BaseURL points to a genuine Gemini v1beta SSE endpoint, not a shim with divergent schema.
- Upgrade the library to pick up schema fixes for newer Gemini API responses.
- Recover by closing the stream and retrying the request — truncated chunks are often transient.
Example fix
// before
text, err := stream.Recv(ctx)
if err != nil { return err }
// after
text, err := stream.Recv(ctx)
if err != nil {
if strings.Contains(err.Error(), "failed to parse stream chunk") {
return fmt.Errorf("bad chunk from endpoint; check BaseURL/schema: %w", err)
}
return err
} Defensive patterns
Strategy: try-catch
Type guard
func isChunkParseErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "failed to parse stream chunk")
} Try / catch
text, err := stream.Recv(ctx)
if err != nil {
if isChunkParseErr(err) {
log.Printf("malformed chunk; closing stream and retrying request")
stream.Close()
return retryRequest(ctx, req)
}
return err
} Prevention
- Point BaseURL only at genuine Gemini v1beta SSE endpoints
- Keep the library updated for Gemini API schema changes
- Bypass SSE-mangling middlewares/proxies for streaming traffic
- Treat parse failures as stream-fatal: close and restart the request
When it happens
Trigger: The SSE 'data:' line's JSON lacked expected fields (candidates/error/usageMetadata shapes changed) or contained invalid/truncated JSON, during a Stream call's Recv loop.
Common situations: Proxy that mangles SSE bodies; pointing BaseURL at a Gemini-compatible gateway with slightly different response schema; Gemini API schema evolution; connection cut mid-JSON.
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 stream chunk: %w
- failed to marshal stream request: %w
- failed to parse stream chunk: %w
- failed to parse stream chunk: %w
- anthropic stream error: %s
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/6d2cce72b6f0d841.
Report an issue: GitHub.