chenhg5/cc-connect · error
dingtalk: create audio request: %w
Error message
dingtalk: create audio request: %w
What it means
This error wraps a failure from http.NewRequestWithContext when constructing the audio voice-message POST to https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend. As with the file equivalent, the URL and method are hardcoded constants, so construction failure is nearly impossible; it exists as a guard.
Source
Thrown at platform/dingtalk/dingtalk.go:1274
requestBody := map[string]interface{}{
"robotCode": p.robotCode,
"userIds": []string{rc.senderStaffId},
"msgKey": "sampleAudio",
"msgParam": msgParamJSON,
}
body, err := json.Marshal(requestBody)
if err != nil {
return fmt.Errorf("dingtalk: marshal audio message: %w", err)
}
slog.Debug("dingtalk: sending voice via oToMessages API", "media_id", mediaID, "duration", durationMs, "user_id", rc.senderStaffId)
req, err := http.NewRequestWithContext(ctx, http.MethodPost,
"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)View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped error for the URL-parse failure
- If the endpoint is now configurable, validate it with url.Parse before use
- Retry if caused by transient resource exhaustion
Example fix
// before
req, err := http.NewRequestWithContext(ctx, http.MethodPost, p.audioEndpoint, bytes.NewReader(body))
// after
if _, err := url.Parse(p.audioEndpoint); err != nil { return fmt.Errorf("dingtalk: invalid audio endpoint: %w", err) }
req, err := http.NewRequestWithContext(ctx, http.MethodPost, p.audioEndpoint, bytes.NewReader(body)) Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := url.Parse("https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend"); err != nil { /* fail fast */ } Try / catch
if err := p.SendAudio(ctx, rc, audio, format); err != nil && strings.Contains(err.Error(), "create audio request") { log.Fatalf("audio request construction failed: %v", err) } Prevention
- Keep the endpoint URL a validated constant
- Validate any dynamic endpoint with url.Parse
- Treat occurrences as bugs, not operational errors
When it happens
Trigger: http.NewRequestWithContext failing while building the sampleAudio request — only under abnormal conditions such as memory exhaustion or if the URL construction is modified to use an invalid dynamic value.
Common situations: Not hit in practice with stock code; appears if developers parameterize the endpoint with a malformed URL.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- create request: %w
- create request: %w
- do request: %w
- create AI card: status=%d, body=%s
- stream AI card: status=%d, body=%s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/a40479b0c49b8769.
Report an issue: GitHub.