chenhg5/cc-connect · error
dingtalk: create file request: %w
Error message
dingtalk: create file request: %w
What it means
This error wraps a failure from http.NewRequestWithContext while building the POST to DingTalk's oToMessages batchSend API when sending a file. NewRequestWithContext only fails on an invalid HTTP method or an unparseable URL, so in practice this almost never fires with the hardcoded constant URL. It is a defensive guard; if you see it, the request could not even be constructed.
Source
Thrown at platform/dingtalk/dingtalk.go:1149
"fileType": ext,
})
requestBody := map[string]any{
"robotCode": p.robotCode,
"userIds": []string{rc.senderStaffId},
"msgKey": "sampleFile",
"msgParam": string(msgParamBytes),
}
body, err := json.Marshal(requestBody)
if err != nil {
return fmt.Errorf("dingtalk: marshal file message: %w", err)
}
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 file 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 file request: %w", err)
}
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(resp.Body)
slog.Debug("dingtalk: oToMessages file response", "status", resp.StatusCode, "body", string(respBody))
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("dingtalk: send file failed: status=%d, body=%s", resp.StatusCode, string(respBody))
}
slog.Info("dingtalk: file message sent", "media_id", mediaID, "name", name, "user", rc.senderStaffId)View on GitHub (pinned to 4000b2338a)
Solutions
- Check the wrapped error (%w) for the real cause — it names the URL parse or method problem
- If the endpoint URL was made configurable, validate it with url.Parse before passing it in
- Retry; transient resource exhaustion resolves itself
- Report a bug if it reproduces with unmodified code
Example fix
// before (dynamic URL)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, cfg.BaseURL+"/v1.0/robot/oToMessages/batchSend", bytes.NewReader(body))
// after (validate first)
u, err := url.Parse(cfg.BaseURL)
if err != nil { return fmt.Errorf("dingtalk: invalid base url: %w", err) }
req, err := http.NewRequestWithContext(ctx, http.MethodPost, u.JoinPath("v1.0/robot/oToMessages/batchSend").String(), bytes.NewReader(body)) Defensive patterns
Strategy: try-catch
Validate before calling
if u, err := url.Parse("https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend"); err != nil { /* fail fast */ } Try / catch
if err := p.SendFile(ctx, rc, data, name); err != nil { if strings.Contains(err.Error(), "create file request") { log.Fatalf("request construction failed: %v", err) } } Prevention
- Don't parameterize the hardcoded endpoint URL without validating it with url.Parse
- Treat this error as a code bug, not a runtime condition
- Wrap endpoint construction in a helper that validates once at startup
When it happens
Trigger: Calling SendFile with a reply context that yields a valid token, but http.NewRequestWithContext failing to construct the request for https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend (invalid URL/method — practically impossible with the hardcoded constants, e.g. memory exhaustion or a malformed internal URL if modified).
Common situations: Only seen in exotic conditions: out-of-memory, or a developer modifying the code to build the URL dynamically (e.g. from config with a bad custom endpoint) producing an unparseable 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
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/bbb94a22e5cfdfb4.
Report an issue: GitHub.