chenhg5/cc-connect · error
dingtalk: send audio failed: status=%d, body=%s
Error message
dingtalk: send audio failed: status=%d, body=%s
What it means
This error is returned when the DingTalk oToMessages batch-send HTTP API responds with a status code other than 200 while sending a voice/audio message. The library treats any non-200 response as a delivery failure and surfaces the raw status and response body so the caller can diagnose the API-side problem. The body usually contains DingTalk's errcode/errmsg explaining the rejection.
Source
Thrown at platform/dingtalk/dingtalk.go:1289
"https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend",
bytes.NewReader(body))
if err != nil {
return fmt.Errorf("dingtalk: create audio request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-acs-dingtalk-access-token", token)
resp, err := p.httpClient.Do(req)
if err != nil {
return fmt.Errorf("dingtalk: send audio request: %w", err)
}
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(resp.Body)
slog.Debug("dingtalk: oToMessages API response", "status", resp.StatusCode, "body", string(respBody))
if resp.StatusCode != 200 {
return fmt.Errorf("dingtalk: send audio failed: status=%d, body=%s", resp.StatusCode, string(respBody))
}
slog.Info("dingtalk: voice message sent successfully", "media_id", mediaID, "conversation_id", rc.conversationId)
return nil
}
// compressAudio compresses audio if it exceeds size limits.
// Uses ffmpeg to convert WAV to MP3 format (DingTalk supported, ~10:1 compression ratio).
func (p *Platform) compressAudio(ctx context.Context, audio []byte, format string) ([]byte, string, error) {
// Only WAV format can be compressed to MP3
if strings.ToLower(format) != "wav" {
return nil, "", fmt.Errorf("only WAV format can be compressed, got: %s", format)
}
return p.compressAudioWithFFmpeg(ctx, audio, format)
}
// compressAudioWithFFmpeg compresses audio using ffmpeg with stdin/stdout pipes.View on GitHub (pinned to 4000b2338a)
Solutions
- Read the body string in the error for DingTalk's errcode/errmsg and address that specific cause (e.g. errcode 40001 → refresh access token).
- Verify appKey/appSecret in config.toml and that the bot is a member of the target conversation.
- Re-upload the media and retry once — the media_id may have expired or the failure was transient (5xx).
- Confirm the target conversationId/chatCode matches an existing group or single chat the bot can message.
Example fix
// before: token cached forever, may expire
accessToken := p.accessToken
// after: refresh when API returns invalid-token errcode
if strings.Contains(respBody, "40001") { _ = p.refreshAccessToken(); return p.sendAudio(...) } Defensive patterns
Strategy: try-catch
Validate before calling
// Go: check token and conversation before sending
if token == "" { return errors.New("no access token") }
if !botInConversation(cid) { return fmt.Errorf("bot not member of %s", cid) } Try / catch
if err := p.sendAudio(ctx, cid, mediaID); err != nil {
var apiErr *APIError
if errors.As(err, &apiErr) { slog.Warn("dingtalk audio rejected", "body", apiErr.Body) }
// retry once on 5xx, refresh token on 401/40001
} Prevention
- Parse DingTalk's errcode/errmsg from the response body on every failure.
- Refresh the access token on 401/errcode 40001 instead of failing hard.
- Verify bot membership in the target conversation during setup, not at send time.
When it happens
Trigger: Sending an audio voice message via p.sendAudio (oToMessages API) where the POST returns 400/401/403/500 — e.g. an invalid or expired access token embedded in the media_id flow, an invalid chatCode/cid, or a media_id that was rejected.
Common situations: Expired or wrong appKey/appSecret credentials producing invalid tokens; sending to a conversationId the bot is not a member of; media upload succeeded but the media_id was for the wrong media type; DingTalk-side rate limiting or transient 5xx.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- http get: %w
- download returned status %d
- qwen tts: empty audio URL in response
- mimo tts: decode audio base64: %w
- create request: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/fc6eac90db72281c.
Report an issue: GitHub.