sipeed/picoclaw · error
failed to decode audio data: %w
Error message
failed to decode audio data: %w
What it means
Returned when choices[0].message.audio.data is present but is not decodable with base64.StdEncoding — the field contains whitespace or line wraps, uses URL-safe base64 ('-'/'_' instead of '+'/'/'), has missing or wrong padding, or is a data-URI ('data:audio/mp3;base64,...') instead of raw base64.
Source
Thrown at pkg/audio/tts/mimo_tts.go:158
Audio struct {
Data string `json:"data"`
} `json:"audio"`
} `json:"message"`
} `json:"choices"`
}
err = json.Unmarshal(body, &payload)
if err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}
if len(payload.Choices) == 0 || payload.Choices[0].Message.Audio.Data == "" {
return nil, fmt.Errorf("invalid TTS response: missing audio data")
}
audioBytes, err := base64.StdEncoding.DecodeString(payload.Choices[0].Message.Audio.Data)
if err != nil {
return nil, fmt.Errorf("failed to decode audio data: %w", err)
}
return io.NopCloser(bytes.NewReader(audioBytes)), nil
}
View on GitHub (pinned to 49183d7e8d)
Solutions
- Log a short prefix/suffix sample of the data field to spot prefixes or line wrapping
- Strip any 'data:...;base64,' prefix and all whitespace before decoding
- Try RawStdEncoding and URLEncoding variants as a compatibility shim
- If it persists, the API contract changed — update the provider or report upstream
Example fix
// before
b, err := base64.StdEncoding.DecodeString(data)
// after
clean := strings.Map(func(r rune) rune {
if r == ' ' || r == '\t' || r == '\r' || r == '\n' {
return -1
}
return r
}, data)
b, err := base64.StdEncoding.DecodeString(clean)
if err != nil {
b, err = base64.RawStdEncoding.DecodeString(clean)
} Defensive patterns
Strategy: try-catch
Type guard
func isBase64Corrupt(err error) bool {
var cie base64.CorruptInputError
return errors.As(err, &cie)
} Try / catch
if err != nil && isBase64Corrupt(err) {
// provider encoding drift: re-synthesize once; if it repeats, the API changed —
// strip data-URI prefixes / whitespace or try alternate encodings, then report upstream
} Prevention
- Keep the mimo provider version current; encoding fixes land there
- Capture a prefix/suffix sample of the data field when this fires
- Prefer the openai-tts provider (raw byte stream) when mimo encoding is unstable
When it happens
Trigger: Provider switches to URL-safe or unpadded base64; a gateway re-encodes or wraps long lines; the API starts prefixing a data-URI to the payload.
Common situations: API version changes on api.xiaomimimo.com; intermediaries that mangle very long strings.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to send request: %w
- failed to read response: %w
- API error (status %d): %s
- failed to decode response: %w
- invalid TTS response: missing audio data
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/cdcf1d66fd4f215c.
Report an issue: GitHub.