chenhg5/cc-connect · error
dingtalk: proactive send request: %w
Error message
dingtalk: proactive send request: %w
What it means
The HTTP transport layer failed while POSTing the proactive message to the DingTalk API. This wraps the client-side network error (DNS failure, connection refused, TLS error, timeout) returned by p.httpClient.Do(req), before any HTTP status is received.
Source
Thrown at platform/dingtalk/dingtalk.go:1692
} else {
return fmt.Errorf("dingtalk: proactive send requires conversationId (group) or senderStaffId (direct)")
}
body, err := json.Marshal(requestBody)
if err != nil {
return fmt.Errorf("dingtalk: marshal proactive message: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(body))
if err != nil {
return fmt.Errorf("dingtalk: create proactive 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: proactive send request: %w", err)
}
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("dingtalk: proactive send failed: status=%d, body=%s", resp.StatusCode, string(respBody))
}
slog.Debug("dingtalk: proactive message sent", "api", apiURL, "status", resp.StatusCode)
return nil
}
var atUserIDRegexp = regexp.MustCompile(`@(\d{4,})`)
// extractAtUserIds extracts @userId patterns from content for DingTalk's atUserIds field.
// Matches @ followed by numeric DingTalk user IDs (e.g. @194252073827812352).
func extractAtUserIds(content string) []string {
matches := atUserIDRegexp.FindAllStringSubmatch(content, -1)View on GitHub (pinned to 4000b2338a)
Solutions
- Check basic connectivity to the DingTalk API host (curl https://api.dingtalk.com) from the host running cc-connect.
- If a proxy is configured in the dingtalk platform options, verify the proxy URL, credentials, and that the proxy is reachable.
- Inspect the wrapped error (%w): context deadline exceeded → increase the HTTP client timeout; connection refused/proxy → fix network or proxy settings.
- Add retry with backoff for transient network failures on this idempotent send path.
Example fix
// before err := p.Send(ctx, rc, msg) // fires once, no timeout budget // after ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() err := p.Send(ctx, rc, msg)
Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout("tcp", "api.dingtalk.com:443", 3*time.Second)
if err != nil {
slog.Warn("dingtalk unreachable", "err", err)
} else {
conn.Close()
} Try / catch
var nerr net.Error
if errors.As(err, &nerr) && nerr.Timeout() {
// retry with backoff
}
if err := p.Send(ctx, rc, msg); err != nil {
slog.Warn("proactive send transport error", "err", err)
} Prevention
- Set a sane HTTP client timeout (5–15s) for the DingTalk client
- Whitelist api.dingtalk.com in firewalls/proxies
- Configure and test the proxy option before deploying
- Add exponential backoff retry for transient errors
When it happens
Trigger: p.httpClient.Do(req) returns a non-nil error for the proactive-send POST — network unreachable, DNS resolution failure, proxy failure, or context deadline exceeded mid-request.
Common situations: No internet access or blocked access to api.dingtalk.com (firewall/corporate proxy); proxy misconfiguration in the platform options; request timeout set too low; DingTalk service outage.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/b8fac34a41df4f34.
Report an issue: GitHub.