micro/go-micro · error

failed to marshal request: %w

Error message

failed to marshal request: %w

What it means

Thrown in the OpenAI provider's non-streaming callAPI when json.Marshal(req) fails while serializing the request map for /v1/chat/completions. Because req is map[string]any, marshaling fails only if some value isn't JSON-encodable (func, channel, cyclic reference, unsupported numeric type like NaN via interface).

Source

Thrown at ai/openai/openai.go:300

		return nil, err
	}
	return nil, io.EOF
}

func (s *openAIStream) Close() error {
	if s.closed {
		return nil
	}
	s.closed = true
	return s.body.Close()
}

// callAPI makes an HTTP request to the OpenAI API
func (p *Provider) callAPI(ctx context.Context, req map[string]any) (*ai.Response, map[string]any, error) {
	// Marshal request
	reqBody, err := json.Marshal(req)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to marshal request: %w", err)
	}

	// Build HTTP request
	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)
	}

	// Set headers
	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("Authorization", "Bearer "+p.opts.APIKey)

	// Make request
	httpResp, err := http.DefaultClient.Do(httpReq)
	if err != nil {
		return nil, nil, fmt.Errorf("API request failed: %w", err)
	}

View on GitHub (pinned to 24529f1404)

Solutions

  1. Inspect the req map keys for values json cannot encode
  2. Constrain request values to JSON-safe types (string, int, float64, bool, slices, maps)
  3. Reject/convert NaN and Inf floats before building the map
  4. Log the map (with a safe encoder) before marshaling to find the offending key

Example fix

// before
temp := math.NaN()
req["temperature"] = temp // json.Marshal error
// after
if !math.IsNaN(temp) && !math.IsInf(temp, 0) {
    req["temperature"] = temp
}
Defensive patterns

Strategy: validation

Validate before calling

if b, err := json.Marshal(req); err != nil || !json.Valid(b) {
    return fmt.Errorf("request not JSON-encodable: %w", err)
}

Prevention

When it happens

Trigger: Calling the provider's non-streaming Complete path where the req map passed to callAPI contains a non-serializable value — custom options, tool definitions built at runtime with bad types, or NaN/Inf floats.

Common situations: Large JSON payloads or special characters in prompts (e.g. unpaired surrogates) can also surface as marshal failures.

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


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