chenhg5/cc-connect · error
dingtalk: create image request: %w
Error message
dingtalk: create image request: %w
What it means
Returned by SendImage when http.NewRequestWithContext fails to construct the POST to DingTalk's robot/oToMessages/batchSend endpoint. This only happens if the HTTP method or URL string is invalid, or ctx is already cancelled, so it indicates a programming bug or an expired context rather than a runtime network issue.
Source
Thrown at platform/dingtalk/dingtalk.go:1054
msgParamBytes, _ := json.Marshal(map[string]string{"photoURL": mediaID})
requestBody := map[string]any{
"robotCode": p.robotCode,
"userIds": []string{rc.senderStaffId},
"msgKey": "sampleImageMsg",
"msgParam": string(msgParamBytes),
}
body, err := json.Marshal(requestBody)
if err != nil {
return fmt.Errorf("dingtalk: marshal image 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 image 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 image request: %w", err)
}
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(resp.Body)
slog.Debug("dingtalk: oToMessages image response", "status", resp.StatusCode, "body", string(respBody))
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("dingtalk: send image failed: status=%d, body=%s", resp.StatusCode, string(respBody))
}
slog.Info("dingtalk: image message sent", "media_id", mediaID, "user", rc.senderStaffId)View on GitHub (pinned to 4000b2338a)
Solutions
- Check that the context passed to SendImage is alive at call time; do not reuse a cancelled context
- Wrap the call and inspect errors.Is(err, context.Canceled) / context.DeadlineExceeded to distinguish cancellation from a bug
- Verify the platform code version — the URL is hard-coded, so a malformed URL would mean a corrupted build
- If cancellation is expected during shutdown, tolerate this error and retry after re-init
Example fix
// before
if err := p.SendImage(ctx, rc, img); err != nil { log.Fatal(err) }
// after
if err := p.SendImage(ctx, rc, img); err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return // shutdown path
}
log.Fatal(err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if ctx.Err() != nil {
return fmt.Errorf("context already done, skip SendImage: %w", ctx.Err())
} Try / catch
if err := p.SendImage(ctx, rc, img); err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return nil // expected during shutdown
}
return fmt.Errorf("dingtalk image send failed: %w", err)
} Prevention
- Always pass a live, non-cancelled context to platform send calls
- Set context deadlines generously enough for network round trips
- Log wrapped errors with %w so root causes stay inspectable
When it happens
Trigger: Calling SendImage while the passed context is already cancelled/deadline-exceeded, or (theoretically) if the hard-coded endpoint URL is malformed.
Common situations: Caller passes a context whose deadline lapsed before the send; shutdown race where engine cancels ctx then still calls SendImage.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/81cd36e8e4459158.
Report an issue: GitHub.