micro/go-micro · error
failed to marshal stream request: %w
Error message
failed to marshal stream request: %w
What it means
Wraps json.Marshal failure when encoding the streaming chat request in the Ollama provider's streamOpenAI (called from Stream). Like the non-streaming variant, it indicates the apiReq map contains values that cannot be serialized to JSON.
Source
Thrown at ai/ollama/ollama.go:333
}
return response, raw, nil
}
func (p *Provider) streamOpenAI(ctx context.Context, req *ai.Request) (ai.Stream, error) {
messages := buildOpenAIMessages(req)
apiReq := map[string]any{
"model": p.opts.Model,
"messages": messages,
"stream": true,
"stream_options": map[string]any{"include_usage": true},
}
if p.opts.MaxTokens > 0 {
apiReq["max_tokens"] = p.opts.MaxTokens
}
reqBody, err := json.Marshal(apiReq)
if err != nil {
return nil, fmt.Errorf("failed to marshal stream request: %w", err)
}
apiURL := strings.TrimRight(p.opts.BaseURL, "/") + p.streamPath()
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))
if err != nil {
return nil, fmt.Errorf("failed to create stream request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("Accept", "text/event-stream")
if p.opts.APIKey != "" {
httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)
}
httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("stream API request failed: %w", err)
}
if httpResp.StatusCode != http.StatusOK {View on GitHub (pinned to 24529f1404)
Solutions
- Audit the values passed into Stream options for non-serializable types
- Replace NaN/Inf floats in temperature/top_p with valid numbers or omit them
- Log the apiReq keys/types on failure to find the offending entry
- Use a typed request struct instead of map[string]any for compile-time safety
Example fix
// before
reqBody, err := json.Marshal(apiReq)
if err != nil {
return nil, fmt.Errorf("failed to marshal stream request: %w", err)
}
// after
reqBody, err := json.Marshal(apiReq)
if err != nil {
return nil, fmt.Errorf("failed to marshal stream request: %w: keys=%v", err, mapKeys(apiReq))
} Defensive patterns
Strategy: validation
Validate before calling
if math.IsNaN(opts.Temperature) || math.IsInf(opts.Temperature, 0) {
return fmt.Errorf("temperature must be finite")
}
if err := json.Marshal(opts); err != nil {
return fmt.Errorf("stream options not serializable: %w", err)
} Type guard
func isJSONSerializable(v any) bool {
_, err := json.Marshal(v)
return err == nil
} Try / catch
stream, err := provider.Stream(ctx, req)
if err != nil {
if strings.Contains(err.Error(), "failed to marshal stream request") {
// audit apiReq fields for channels/funcs/cycles/NaN
}
return err
} Prevention
- Pass only JSON-compatible values into stream options
- Guard sampling floats against NaN/Inf
- Avoid func/cyclic fields in request metadata
- Unit-test Stream with realistic option sets
When it happens
Trigger: json.Marshal(apiReq) fails in streamOpenAI (called from Stream) — the request map includes non-JSON-serializable values: channels, funcs, cyclic references, or NaN/Inf numbers in options like temperature/top_p/max_tokens.
Common situations: Caller-supplied tools or options with unsupported types; NaN/Inf computed sampling parameters; cyclic metadata attached to the request.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- failed to marshal request: %w
- failed to parse stream chunk: %w
- failed to marshal stream request: %w
- failed to parse stream chunk: %w
- failed to parse response: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/e71e53ee73c09a8d.
Report an issue: GitHub.