chenhg5/cc-connect · error
upload init: %w
Error message
upload init: %w
What it means
After sending the aibot_upload_media_init frame, uploadWSMedia waits for the server's ack via writeAndWaitFrameWithTimeout with wsMediaAckTimeout. Any failure to write the frame or receive the ack within the timeout is wrapped as "upload init: %w", so the root cause (deadline exceeded, connection closed, write error) is preserved in the chain.
Source
Thrown at platform/wecom/websocket_outbound_media.go:68
return "", fmt.Errorf("media too large: %d chunks exceeds maximum %d", totalChunks, wecomWSUploadMaxChunks)
}
sum := md5.Sum(data)
initReqID := p.generateReqID("aibot_upload_media_init")
initFrame := map[string]any{
"cmd": "aibot_upload_media_init",
"headers": map[string]string{"req_id": initReqID},
"body": map[string]any{
"type": mediaType,
"filename": filename,
"total_size": len(data),
"total_chunks": totalChunks,
"md5": hex.EncodeToString(sum[:]),
},
}
initResp, err := p.writeAndWaitFrameWithTimeout(ctx, initFrame, initReqID, wsMediaAckTimeout)
if err != nil {
return "", fmt.Errorf("upload init: %w", err)
}
var initBody struct {
UploadID string `json:"upload_id"`
}
if err := json.Unmarshal(initResp.Body, &initBody); err != nil {
return "", fmt.Errorf("decode upload init response: %w", err)
}
if initBody.UploadID == "" {
return "", fmt.Errorf("upload init: empty upload_id")
}
for i := 0; i < totalChunks; i++ {
start := i * wecomWSUploadChunkSize
end := start + wecomWSUploadChunkSize
if end > len(data) {
end = len(data)
}
reqID := p.generateReqID("aibot_upload_media_chunk")View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped root error: context.DeadlineExceeded means raise/investigate wsMediaAckTimeout; connection errors mean reconnect first.
- Retry the upload with backoff — a transient network hiccup or missed ack often succeeds on a second attempt.
- Verify the WebSocket connection is healthy before uploading (ping/pong or reconnect on stale connections).
- Check network path to WeCom (proxy, firewall, corporate egress) if failures are persistent.
Example fix
// before
mediaID, err := p.uploadWSMedia(ctx, "image", name, data)
if err != nil {
return err
}
// after
mediaID, err := p.uploadWSMedia(ctx, "image", name, data)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
return fmt.Errorf("wecom: media upload init timed out; check WebSocket connectivity and wsMediaAckTimeout: %w", err)
}
return fmt.Errorf("wecom: media upload failed: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
if p.wsConn == nil || isStale(p.wsConn) {
if err := p.reconnect(ctx); err != nil {
return fmt.Errorf("wecom ws not connected: %w", err)
}
} Try / catch
mediaID, err := p.uploadWSMedia(ctx, mt, name, data)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) || isConnErr(err) {
return retryWithBackoff(ctx, 3, func() (string, error) { return p.uploadWSMedia(ctx, mt, name, data) })
}
return "", err
} Prevention
- Keep the WebSocket alive with periodic ping/pong and reconnect on missed pongs.
- Size wsMediaAckTimeout generously for high-latency networks (e.g. >=30s for media init).
- Wrap uploads in bounded exponential-backoff retry for transient failures.
- Monitor WS disconnect/proxy logs; corporate proxies often kill idle sockets.
When it happens
Trigger: SendImage/SendFile when the WeCom WebSocket connection is slow, saturated, dead, or the server never acks aibot_upload_media_init within wsMediaAckTimeout; also when the frame write itself fails.
Common situations: Unstable or high-latency network to WeCom; WS connection dropped by a proxy/firewall mid-session; server overloaded or slow to ack; timeout too aggressive for large-scale deployments; stale connection that only fails on the next write.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/5ed8d67162732220.
Report an issue: GitHub.