chenhg5/cc-connect · error

mimo tts: marshal request: %w

Error message

mimo tts: marshal request: %w

What it means

This error wraps json.Marshal failing while encoding the MiMo (Xiaomi MiMo-V2.5-TTS) request body inside Synthesize. Marshaling a plain map[string]any of strings/bools essentially cannot fail in practice, so hitting this indicates corrupted inputs (e.g. strings containing invalid content is not possible for JSON, but unsupported types or a canceled context via custom marshalers would). Practically it signals an internal/programming error building the payload.

Source

Thrown at core/tts.go:470

	// Per MiMo docs: synthesis text MUST live on an assistant message; the
	// user message is optional for built-in-voice mode but required for
	// voicedesign. Sending an empty user content stays valid across all
	// three model variants.
	reqBody := map[string]any{
		"model": m.Model,
		"messages": []map[string]any{
			{"role": "user", "content": ""},
			{"role": "assistant", "content": text},
		},
		"audio": map[string]any{
			"format": "wav",
			"voice":  voice,
		},
	}
	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		return nil, "", fmt.Errorf("mimo tts: marshal request: %w", err)
	}

	url := strings.TrimRight(m.BaseURL, "/") + "/chat/completions"
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(jsonData))
	if err != nil {
		return nil, "", fmt.Errorf("mimo tts: create request: %w", err)
	}
	// MiMo authenticates via "api-key" header, not "Authorization: Bearer".
	req.Header.Set("api-key", m.APIKey)
	req.Header.Set("Content-Type", "application/json")

	resp, err := m.Client.Do(req)
	if err != nil {
		return nil, "", fmt.Errorf("mimo tts: request: %w", err)
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Inspect the wrapped %w error to identify which value failed to marshal.
  2. Ensure only JSON-serializable types (string, bool, number) are put into the request map.
  3. If injecting config-derived values, coerce them to strings/float64 before adding to the payload.
  4. Treat as a bug report if reproducible with the stock code path.

Example fix

// before
opts := map[string]any{"format": "wav", "voice": voice, "extra": someUnsupportedValue}
// after
opts := map[string]any{"format": "wav", "voice": voice} // only JSON-serializable values
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure payload values are JSON-encodable
if _, err := json.Marshal(reqBody); err != nil { return fmt.Errorf("invalid tts payload: %w", err) }

Try / catch

if err != nil && strings.Contains(err.Error(), "marshal request") {
    // programming bug in payload construction — log and report
}

Prevention

When it happens

Trigger: A value in the request map implements json.Marshaler and returns an error; unsupported type (chan, func, complex) placed in the options map — only possible if the payload construction changes; effectively never with the current literal map.

Common situations: Rare; mostly seen if someone modifies the request body construction to inject dynamic values (e.g. non-string options from config) that aren't JSON-serializable.

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 chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/ef5666b0d4048072. Report an issue: GitHub.