sipeed/picoclaw · error
failed to send request: %w
Error message
failed to send request: %w
What it means
Returned by MimoTTSProvider.Synthesize when httpClient.Do fails before any response is received. The error is a *url.Error wrapping DNS failure, connection refused, TLS handshake problems, the fixed 60s client timeout, proxy failures, or context cancellation. Nothing about the request payload is at fault.
Source
Thrown at pkg/audio/tts/mimo_tts.go:124
"stream": false,
}
jsonData, err := json.Marshal(reqBody)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %w", err)
}
req, err := http.NewRequestWithContext(ctx, "POST", t.apiBase, bytes.NewReader(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Api-Key", t.apiKey)
resp, err := t.httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to send request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(body))
}
var payload struct {
Choices []struct {
Message struct {
Audio struct {
Data string `json:"data"`
} `json:"audio"`View on GitHub (pinned to 49183d7e8d)
Solutions
- Verify reachability: curl -sS https://api.xiaomimimo.com/v1/chat/completions
- If a proxy is required, pass a parseable proxyURL — invalid ones are dropped with only a log warning
- Retry with exponential backoff; transient transport errors are the norm
- For long texts, split the input or build the provider with a longer client timeout
Example fix
// before
stream, err := mimo.Synthesize(ctx, longText)
// after (retry transient transport errors)
var stream io.ReadCloser
err := retryN(3, time.Second, func() error {
var e error
stream, e = mimo.Synthesize(ctx, longText)
var ue *url.Error
if errors.As(e, &ue) && !errors.Is(e, context.Canceled) {
return e // retry
}
return nil
}) Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout(`tcp`, `api.xiaomimimo.com:443`, 3*time.Second)
if err != nil {
return fmt.Errorf(`mimo tts endpoint unreachable: %w`, err)
}
_ = conn.Close() Type guard
func isTransientTransport(err error) bool {
var ue *url.Error
return errors.As(err, &ue) && !errors.Is(err, context.Canceled)
} Try / catch
var stream io.ReadCloser
err := retryN(3, time.Second, func() error {
var e error
stream, e = provider.Synthesize(ctx, text)
if e != nil && isTransientTransport(e) {
return e
}
return nil // stop on non-transport errors
}) Prevention
- Verify egress to api.xiaomimimo.com:443 before enabling mimo TTS
- Pass a valid proxyURL when a proxy is required — unparseable ones are dropped with a warning
- Split very long texts; the client timeout is fixed at 60s
When it happens
Trigger: api.xiaomimimo.com unreachable (DNS/firewall); proxyURL passed to NewMimoTTSProvider unparseable (it is silently dropped with a warning); client.Timeout of 60s exceeded for long texts; the caller's context canceled mid-request.
Common situations: Air-gapped or firewalled deployments; corporate proxy requirements; very long synthesis inputs exceeding the fixed timeout; intermittent connectivity.
Related errors
- request failed: %w
- failed to read response: %w
- failed to send request: %w
- Failed to load config
- Failed to fetch config
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/6ab5275b065fea57.
Report an issue: GitHub.