chenhg5/cc-connect · error
download returned status %d
Error message
download returned status %d
What it means
The DingTalk audio download request to the resolved download URL completed but returned a non-200 HTTP status, so no audio bytes are read; typically an expired download code, auth failure, or CDN error page.
Source
Thrown at platform/dingtalk/dingtalk.go:657
p.handler(p, msg)
}
func (p *Platform) downloadAudio(downloadCode string) ([]byte, string, error) {
// Get download URL
downloadURL, err := p.getDownloadURL(downloadCode)
if err != nil {
return nil, "", fmt.Errorf("get download URL: %w", err)
}
// Download audio file
resp, err := p.httpClient.Get(downloadURL)
if err != nil {
return nil, "", fmt.Errorf("http get: %w", err)
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, "", fmt.Errorf("download returned status %d", resp.StatusCode)
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, "", fmt.Errorf("read response: %w", err)
}
// Determine MIME type from Content-Type header
mimeType := resp.Header.Get("Content-Type")
if mimeType == "" {
mimeType = "audio/amr" // Default to AMR if not specified
}
return data, mimeType, nil
}
func (p *Platform) getDownloadURL(downloadCode string) (string, error) {
token, err := p.getAccessToken()View on GitHub (pinned to 4000b2338a)
Solutions
- Obtain a fresh download URL immediately before downloading instead of caching it across messages.
- Check the status code in the error to distinguish 403 (auth/permission) from 404/410 (expired URL).
- Verify robotCode matches the robot that received the message so the CDN authorizes the download.
- Retry once on 5xx; treat 4xx as non-retryable.
Defensive patterns
Strategy: retry
Validate before calling
// No pre-call API check possible; guard by freshness instead: // only call downloadAudio with a downloadCode fetched in the current message handler, // never one persisted from an earlier message.
Try / catch
if err != nil && strings.Contains(err.Error(), "download returned status") {
switch {
case strings.Contains(err.Error(), "403"):
// permission/robot mismatch: fix robotCode, do not retry
default:
// expired URL or transient 5xx: fetch a fresh URL and retry once
}
} Prevention
- Never cache download URLs; resolve them per message
- Ensure robotCode matches the receiving robot
- Retry only 5xx/expired-URL statuses; treat 4xx as permanent
When it happens
Trigger: DingTalk's file CDN or an intermediary returned 403/404/410/etc. for the downloadURL during p.httpClient.Get in downloadAudio.
Common situations: Expired download URL (very common — DingTalk URLs are short-lived); downloadCode was reused after its URL expired; permission/robot mismatch so the CDN refuses the download; CDN transient 5xx.
Related errors
- http get: %w
- dingtalk: send audio failed: status=%d, body=%s
- HTTP GET %s: status %d
- create request: %w
- do request: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/ab87bc766b98ffed.
Report an issue: GitHub.