micro/go-micro · error

failed to parse stream chunk: %w

Error message

failed to parse stream chunk: %w

What it means

Thrown in openAIStream.Recv when a SSE data payload cannot be unmarshaled into the expected chunk struct {choices:[{delta:{content}}],usage}. The provider reads 'data:' lines from the event stream and JSON-decodes each; a failure means the payload wasn't the expected ChatCompletionChunk shape. The '[DONE]' sentinel and usage-only final chunks are handled separately.

Source

Thrown at ai/openai/openai.go:266

		}
		data := strings.TrimSpace(strings.TrimPrefix(line, "data:"))
		if data == "[DONE]" {
			return nil, io.EOF
		}
		var chunk struct {
			Choices []struct {
				Delta struct {
					Content string `json:"content"`
				} `json:"delta"`
			} `json:"choices"`
			Usage *struct {
				PromptTokens     int `json:"prompt_tokens"`
				CompletionTokens int `json:"completion_tokens"`
				TotalTokens      int `json:"total_tokens"`
			} `json:"usage"`
		}
		if err := json.Unmarshal([]byte(data), &chunk); err != nil {
			return nil, fmt.Errorf("failed to parse stream chunk: %w", err)
		}
		if len(chunk.Choices) > 0 && chunk.Choices[0].Delta.Content != "" {
			return &ai.Response{Reply: chunk.Choices[0].Delta.Content}, nil
		}
		// Final chunk (after include_usage) carries token usage and no content.
		if chunk.Usage != nil {
			return &ai.Response{Usage: ai.Usage{
				InputTokens:  chunk.Usage.PromptTokens,
				OutputTokens: chunk.Usage.CompletionTokens,
				TotalTokens:  chunk.Usage.TotalTokens,
			}}, nil
		}
		continue
	}
	if err := s.scanner.Err(); err != nil {
		return nil, err
	}
	return nil, io.EOF

View on GitHub (pinned to 24529f1404)

Solutions

  1. Log the raw 'data' string that failed to decode to see the actual payload
  2. Check for an in-stream {"error":{...}} object and surface it as an error instead of unmarshaling as a chunk
  3. Confirm the endpoint truly implements OpenAI chat-completions streaming schema, or point at the official API
  4. Update gateway/proxy so SSE frames are passed through unmodified

Example fix

// before
if err := json.Unmarshal([]byte(data), &chunk); err != nil {
    return nil, fmt.Errorf("failed to parse stream chunk: %w", err)
}
// after
var probe struct{ Error *struct{ Message string `json:"message"` } `json:"error"` }
if json.Unmarshal([]byte(data), &probe) == nil && probe.Error != nil {
    return nil, fmt.Errorf("stream error: %s", probe.Error.Message)
}
if err := json.Unmarshal([]byte(data), &chunk); err != nil {
    return nil, fmt.Errorf("failed to parse stream chunk: %w", err)
}
Defensive patterns

Strategy: try-catch

Try / catch

resp, err := stream.Recv()
if err != nil {
    if strings.Contains(err.Error(), "failed to parse stream chunk") {
        // log raw payload; check endpoint OpenAI-compatibility
    }
    return err
}

Prevention

When it happens

Trigger: During stream consumption: the server sends a data payload that isn't a chat completion chunk — an error JSON object ({"error":{...}}) delivered in-stream, a non-OpenAI-compatible endpoint with a different SSE schema, or a truncated/garbled line from a dropped connection.

Common situations: Pointing BaseURL at a 'OpenAI-compatible' service (LM Studio, vLLM, older proxy) whose chunk schema differs; streaming error events (e.g. content_filter, overload) that arrive as JSON without a choices array; gateway mangling SSE frames.

Understand the failure class

Related errors


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