micro/go-micro · error

failed to parse stream chunk: %w

Error message

failed to parse stream chunk: %w

What it means

During streaming, Recv() received an SSE data payload from the OpenAI-compatible endpoint that could not be unmarshaled into the expected chat.completion.chunk structure. This means the stream delivered bytes that are not valid JSON or do not match the expected schema.

Source

Thrown at ai/ollama/ollama.go:408

		}
		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
		}
		if chunk.Usage != nil {
			return &ai.Response{Usage: ai.Usage{
				InputTokens:  chunk.Usage.PromptTokens,
				OutputTokens: chunk.Usage.CompletionTokens,
				TotalTokens:  chunk.Usage.TotalTokens,
			}}, nil
		}
	}
	if err := s.scanner.Err(); err != nil {
		return nil, err
	}
	return nil, io.EOF
}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Check the wrapped %w error — json.Unmarshal messages reveal whether it's invalid syntax or a type mismatch.
  2. Verify no proxy/middleware is modifying the response stream.
  3. Ensure BaseURL points at a genuine OpenAI-compatible endpoint.
  4. Retry the stream; a single corrupted chunk may be transient, or re-issue the request if the stream aborted.

Example fix

// before
resp, err := stream.Recv(ctx) // may return parse error; code ignores
// after
resp, err := stream.Recv(ctx)
if err != nil {
    log.Printf("stream ended or chunk parse failed: %v", err)
    return err // abort and restart the stream
}
Defensive patterns

Strategy: retry

Try / catch

for {
    resp, err := stream.Recv(ctx)
    if err != nil {
        if strings.Contains(err.Error(), "failed to parse stream chunk") {
            // stream is corrupt; restart the whole request
            return restartStream(ctx, req)
        }
        return err // io.EOF = clean end
    }
    handle(resp)
}

Prevention

When it happens

Trigger: Calling Recv() on the ai.Stream returned by Stream() in cloud mode when a data: line contains non-JSON content, truncated JSON, or an unexpected error payload shape from the server.

Common situations: Proxy or load balancer corrupting/interleaving the SSE stream, response truncated by a timeout or connection reset, server pushing a non-standard error event mid-stream, custom BaseURL pointing at a non-OpenAI-compatible mock.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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