micro/go-micro · error
failed to marshal request: %w
Error message
failed to marshal request: %w
What it means
The Together AI provider's callAPI could not JSON-marshal the request map before POSTing to /v1/chat/completions. Since the map holds plain JSON-able values, this practically means a non-serializable value (NaN/Inf float, channel, func, cyclic reference) entered the request map.
Source
Thrown at ai/together/together.go:161
}
return resp, nil
}
// maxToolRounds bounds the tool-execution loop in a single Generate. Each
// round is a model call plus the tools it asks for, so this is the ceiling on
// one question's cost as well as its length; it is high enough that no honest
// piece of multi-step work reaches it.
const maxToolRounds = 12
func (p *Provider) Stream(ctx context.Context, req *ai.Request, opts ...ai.GenerateOption) (ai.Stream, error) {
return openaiapi.Stream(ctx, p.opts, req, "/v1/chat/completions")
}
func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, map[string]any, error) {
reqBody, err := json.Marshal(req)
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal 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, nil, fmt.Errorf("failed to create request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)
httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
return nil, nil, fmt.Errorf("API request failed: %w", err)
}
defer httpResp.Body.Close()
respBody, _ := io.ReadAll(httpResp.Body)View on GitHub (pinned to 24529f1404)
Solutions
- Validate sampling params: reject NaN/Inf for temperature/top_p before building the map
- Sanitize or default non-finite floats (math.IsNaN/IsInf) when constructing the request
- Marshal the request map in a test to reproduce the exact error message
- Ensure only JSON-representable values are placed into the request map
Example fix
// before
temp := computeTemperature() // may be NaN
req["temperature"] = temp
// after
if math.IsNaN(temp) || math.IsInf(temp, 0) { temp = 0.7 }
req["temperature"] = temp Defensive patterns
Strategy: validation
Validate before calling
func sanitizeParams(params map[string]any) {
for k, v := range params {
if f, ok := v.(float64); ok && (math.IsNaN(f) || math.IsInf(f, 0)) {
params[k] = nil // or a default
}
}
}
// call before passing the map to the provider Type guard
func isJSONSafeFloat(f float64) bool {
return !math.IsNaN(f) && !math.IsInf(f, 0)
} Try / catch
resp, err := provider.Generate(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed to marshal request") {
return fmt.Errorf("non-JSON value in Together request map: %w", err)
} Prevention
- Check temperature/top_p for NaN/Inf after any computation
- Restrict request maps to JSON-primitive types
- Add a marshal unit test for every request shape
- Default non-finite sampling params to library defaults
When it happens
Trigger: The req map[string]any built for the Together chat API contains a value json.Marshal rejects — e.g. NaN produced by numeric post-processing of temperature/top_p, or a custom field with an unsupported type.
Common situations: Dynamically assembled sampling params where a computation yields NaN (0/0 division), callers passing structured objects that contain funcs or channels into the request map.
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 marshal stream request: %w
- failed to marshal request: %w
- failed to create request: %w
- failed to parse response: %w
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/bac0c1d670062e7a.
Report an issue: GitHub.