chenhg5/cc-connect · error
upload request: %w
Error message
upload request: %w
What it means
The HTTP transport itself failed when POSTing the multipart media upload to the DingTalk API — the request never got a usable response. p.httpClient.Do returned an error such as DNS failure, TCP connect refused/timeout, TLS error, or context cancellation.
Source
Thrown at platform/dingtalk/dingtalk.go:1372
if _, err := part.Write(data); err != nil {
return "", fmt.Errorf("write media data: %w", err)
}
if err := writer.Close(); err != nil {
return "", fmt.Errorf("close multipart writer: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, uploadURL, body)
if err != nil {
return "", fmt.Errorf("create upload request: %w", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
resp, err := p.httpClient.Do(req)
if err != nil {
return "", fmt.Errorf("upload request: %w", err)
}
defer func() { _ = resp.Body.Close() }()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("read upload response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("upload returned status %d: %s", resp.StatusCode, respBody)
}
slog.Debug("dingtalk: media upload response", "status", resp.StatusCode, "body", string(respBody))
var uploadResp struct {
ErrCode int `json:"errcode"`
ErrMsg string `json:"errmsg"`
MediaID string `json:"media_id"`View on GitHub (pinned to 4000b2338a)
Solutions
- Verify connectivity: curl -v https://oapi.dingtalk.com/media/upload from the host.
- Check proxy/HTTPS_PROXY settings and corporate CA certs (SSL_CERT_FILE/SSL_CERT_DIR).
- Increase the httpClient timeout or pass a longer-lived context for large media uploads.
- Retry with backoff for transient DNS/connect failures; alert on persistent network loss.
Example fix
// before
resp, err := p.httpClient.Do(req)
if err != nil { return "", fmt.Errorf("upload request: %w", err) }
// after
resp, err := p.httpClient.Do(req)
if err != nil {
if ctx.Err() != nil { return "", fmt.Errorf("upload canceled: %w", ctx.Err()) }
return "", retryable(fmt.Errorf("upload request: %w", err))
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight connectivity check
resp, err := http.Head("https://oapi.dingtalk.com")
if err != nil { return fmt.Errorf("dingtalk unreachable: %w", err) }
resp.Body.Close() Try / catch
resp, err := p.httpClient.Do(req)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) { return "", err }
return "", retryWithBackoff(err) // transient network error
} Prevention
- Set a generous httpClient timeout for media uploads.
- Configure proxy/CA env vars correctly in containerized deployments.
- Add retry with exponential backoff for transient transport errors.
- Include DingTalk endpoint reachability in startup health checks.
When it happens
Trigger: uploadMedia calls p.httpClient.Do(req) for https://oapi.dingtalk.com/media/upload and the network layer errors before/without an HTTP status line.
Common situations: No outbound internet access or DNS failure on the host; corporate proxy/firewall blocking oapi.dingtalk.com; TLS interception with an untrusted CA; context deadline exceeded because upload of a big media file was too slow; daemon run in an isolated container network.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/46a1241b64c9f81e.
Report an issue: GitHub.