chenhg5/cc-connect · error
qwen tts: marshal request: %w
Error message
qwen tts: marshal request: %w
What it means
QwenTTS.Synthesize builds the JSON request body (model, input text, optional language_type) with json.Marshal. If marshaling fails it wraps the error as 'qwen tts: marshal request'. This is nearly impossible with the fixed struct shape and typically indicates a programming-level serialization problem.
Source
Thrown at core/tts.go:136
func (q *QwenTTS) Synthesize(ctx context.Context, text string, opts TTSSynthesisOpts) ([]byte, string, error) {
voice := opts.Voice
if voice == "" {
voice = "Cherry"
}
reqBody := map[string]any{
"model": q.Model,
}
input := map[string]any{
"text": text,
"voice": voice,
}
if opts.LanguageType != "" {
input["language_type"] = opts.LanguageType
}
reqBody["input"] = input
jsonData, err := json.Marshal(reqBody)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: marshal request: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, q.BaseURL, bytes.NewReader(jsonData))
if err != nil {
return nil, "", fmt.Errorf("qwen tts: create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+q.APIKey)
req.Header.Set("Content-Type", "application/json")
resp, err := q.Client.Do(req)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, "", fmt.Errorf("qwen tts: read response: %w", err)View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped error and the values placed into the request body; remove any non-JSON-serializable values.
- Ensure opts fields (Text, LanguageType) are plain strings.
- This is an internal bug if you only pass normal string options — file/debug the code constructing reqBody.
Example fix
// before
reqBody["input"] = someRuntimeValue // may be unserializable
// after
reqBody["input"] = fmt.Sprintf("%v", someRuntimeValue) Defensive patterns
Strategy: try-catch
Validate before calling
if opts.Text == "" || opts.LanguageType == "" && false {
// only plain strings allowed in request body
}
// ensure any custom values injected into the request are JSON-encodable
if err := json.Marshal(reqBody); err != nil { /* fix value types before calling Synthesize */ } Try / catch
audio, url, err := q.Synthesize(ctx, text, opts)
if err != nil {
var se *fmt.wrapError
if errors.As(err, &se) && strings.Contains(err.Error(), "marshal request") {
slog.Error("qwen tts request construction bug", "err", err)
}
return err
} Prevention
- Keep request body values restricted to JSON-safe types (string, number, bool).
- Never insert runtime arbitrary values into the request map without conversion.
- Cover Synthesize with a unit test asserting request JSON shape.
When it happens
Trigger: json.Marshal(reqBody) returns an error — for a map[string]any/struct of plain strings this effectively only happens if an unsupported value type (e.g. a channel, func, or cyclic value) was injected into reqBody.
Common situations: Custom code that mutates the request map with non-JSON-serializable values before Synthesize is called; generics/refactor code placing a wrong-typed value into the 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
- qwen tts: parse response: %w
- openai tts: marshal request: %w
- mimo tts: marshal request: %w
- marshal: %w
- codex app-server encode: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/00b9d6892d042de4.
Report an issue: GitHub.