{"record":{"id":"a40479b0c49b8769","repo":"chenhg5/cc-connect","slug":"dingtalk-create-audio-request-w","errorCode":null,"errorMessage":"dingtalk: create audio request: %w","messagePattern":"dingtalk: create audio request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":1274,"sourceCode":"\trequestBody := map[string]interface{}{\n\t\t\"robotCode\": p.robotCode,\n\t\t\"userIds\":   []string{rc.senderStaffId},\n\t\t\"msgKey\":    \"sampleAudio\",\n\t\t\"msgParam\":  msgParamJSON,\n\t}\n\n\tbody, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: marshal audio message: %w\", err)\n\t}\n\n\tslog.Debug(\"dingtalk: sending voice via oToMessages API\", \"media_id\", mediaID, \"duration\", durationMs, \"user_id\", rc.senderStaffId)\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost,\n\t\t\"https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend\",\n\t\tbytes.NewReader(body))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: create audio request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"x-acs-dingtalk-access-token\", token)\n\n\tresp, err := p.httpClient.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: send audio request: %w\", err)\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tslog.Debug(\"dingtalk: oToMessages API response\", \"status\", resp.StatusCode, \"body\", string(respBody))\n\n\tif resp.StatusCode != 200 {\n\t\treturn fmt.Errorf(\"dingtalk: send audio failed: status=%d, body=%s\", resp.StatusCode, string(respBody))\n\t}\n\n\tslog.Info(\"dingtalk: voice message sent successfully\", \"media_id\", mediaID, \"conversation_id\", rc.conversationId)","sourceCodeStart":1256,"sourceCodeEnd":1292,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L1256-L1292","documentation":"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.","triggerScenarios":"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.","commonSituations":"Not hit in practice with stock code; appears if developers parameterize the endpoint with a malformed URL.","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"],"exampleFix":"// before\nreq, err := http.NewRequestWithContext(ctx, http.MethodPost, p.audioEndpoint, bytes.NewReader(body))\n// after\nif _, err := url.Parse(p.audioEndpoint); err != nil { return fmt.Errorf(\"dingtalk: invalid audio endpoint: %w\", err) }\nreq, err := http.NewRequestWithContext(ctx, http.MethodPost, p.audioEndpoint, bytes.NewReader(body))","handlingStrategy":"try-catch","validationCode":"if _, err := url.Parse(\"https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend\"); err != nil { /* fail fast */ }","typeGuard":null,"tryCatchPattern":"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) }","preventionTips":["Keep the endpoint URL a validated constant","Validate any dynamic endpoint with url.Parse","Treat occurrences as bugs, not operational errors"],"tags":["dingtalk","http","request"],"backgroundTag":"api-request-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}