micro/go-micro · error
failed to marshal stream request: %w
Error message
failed to marshal stream request: %w
What it means
Thrown in the OpenAI provider's Stream when json.Marshal(apiReq) fails while building the streaming request body. The apiReq is a map[string]any, so marshaling only fails for values that are not JSON-encodable (e.g. channels, funcs, cyclic structures) — rare in practice since options come from typed provider opts.
Source
Thrown at ai/openai/openai.go:211
}
if req.Prompt != "" {
messages = append(messages, map[string]any{"role": "user", "content": req.Prompt})
}
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
}
if p.opts.Effort != "" {
apiReq["reasoning_effort"] = p.opts.Effort
}
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, "/") + "/v1/chat/completions"
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")
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 {
defer httpResp.Body.Close()
respBody, _ := io.ReadAll(httpResp.Body)
return nil, fmt.Errorf("stream API error (%s): %s", httpResp.Status, string(respBody))View on GitHub (pinned to 24529f1404)
Solutions
- Inspect the apiReq map contents for non-JSON-encodable values
- Constrain options to strings, numbers, booleans, and slices/maps thereof
- Ensure any middleware copying/deriving the map doesn't inject functions or channels
- Log the map before marshaling to identify the offending key
Example fix
// before apiReq["tools"] = someFunc // not JSON-encodable // after apiReq["tools"] = toolDefsJSONCompatible
Defensive patterns
Strategy: validation
Validate before calling
func isJSONSafe(v any) bool {
b, err := json.Marshal(v)
return err == nil && json.Valid(b)
}
// call isJSONSafe(apiReq) before provider.Stream Prevention
- Build request maps only from JSON-safe primitives
- Avoid injecting funcs/channels into option maps
- Add a one-off json.Valid sanity check in tests for request builders
When it happens
Trigger: Calling Stream() when the assembled apiReq map contains a value json.Marshal cannot encode — typically only possible if a caller injected a non-serializable value through custom options or a middleware mutating the request map.
Common situations: Custom option injection putting a func or unsupported type into the request map; a wrapping layer building the map dynamically with bad values; almost never hit with standard string/number options.
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 parse stream chunk: %w
- failed to marshal request: %w
- failed to parse stream chunk: %w
- failed to marshal request: %w
- failed to marshal stream request: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/af62f42aceca2fbe.
Report an issue: GitHub.