{"record":{"id":"4f508c7edd543313","repo":"chenhg5/cc-connect","slug":"wecom-ws-ack-timeout-waiting-for-s","errorCode":null,"errorMessage":"wecom-ws: ack timeout waiting for %s","messagePattern":"wecom-ws: ack timeout waiting for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wecom/websocket.go","lineNumber":593,"sourceCode":"\treturn p.writeAndWaitAckWithTimeout(ctx, frame, reqID, wsAckTimeout)\n}\n\nfunc (p *WSPlatform) writeAndWaitAckWithTimeout(ctx context.Context, frame map[string]any, reqID string, timeout time.Duration) error {\n\tresult, err := p.writeAndWaitResult(ctx, frame, reqID, timeout)\n\tif errors.Is(err, errWSAckTimeout) {\n\t\tslog.Debug(\"wecom-ws: ack timeout, proceeding\", \"req_id\", reqID)\n\t\treturn nil\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn result.err\n}\n\nfunc (p *WSPlatform) writeAndWaitAckStrict(ctx context.Context, frame map[string]any, reqID string, timeout time.Duration) error {\n\tresult, err := p.writeAndWaitResult(ctx, frame, reqID, timeout)\n\tif errors.Is(err, errWSAckTimeout) {\n\t\treturn fmt.Errorf(\"wecom-ws: ack timeout waiting for %s\", reqID)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn result.err\n}\n\nfunc (p *WSPlatform) writeAndWaitFrameWithTimeout(ctx context.Context, frame map[string]any, reqID string, timeout time.Duration) (wsFrame, error) {\n\tresult, err := p.writeAndWaitResult(ctx, frame, reqID, timeout)\n\tif errors.Is(err, errWSAckTimeout) {\n\t\treturn wsFrame{}, fmt.Errorf(\"wecom-ws: ack timeout waiting for %s\", reqID)\n\t}\n\tif err != nil {\n\t\treturn wsFrame{}, err\n\t}\n\tif result.err != nil {\n\t\treturn wsFrame{}, result.err\n\t}","sourceCodeStart":575,"sourceCodeEnd":611,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wecom/websocket.go#L575-L611","documentation":"Timeout sentinel surfacing from writeAndWaitAckStrict: the frame with the given req_id was written to the WeCom WebSocket but no server ack arrived within the configured timeout (errWSAckTimeout from writeAndWaitResult). Unlike the non-strict writeAndWaitAck variant, which logs and proceeds, the strict path — used by sendWSMediaMessage where the ack carries the operation result — returns the timeout as a hard error.","triggerScenarios":"Thrown at platform/wecom/websocket.go:593 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the media upload once: transient ack loss is common on the long-lived socket","Verify network health and WebSocket keepalive/heartbeat cadence if timeouts recur","Consider whether the strict variant is required — the lenient variant already proceeds on timeout for text frames","Log req_id (already included) to correlate with any late ack and avoid double-sends on manual retry"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}