{"record":{"id":"36062308896d8c29","repo":"chenhg5/cc-connect","slug":"subscribe-w-360623","errorCode":null,"errorMessage":"subscribe: %w","messagePattern":"subscribe: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wecom/websocket.go","lineNumber":238,"sourceCode":"\t\t})\n\t\tfor _, k := range staleKeys {\n\t\t\tp.pendingAcks.Delete(k)\n\t\t}\n\t}()\n\n\t// Send subscribe (auth) frame\n\t// Format: { cmd: \"aibot_subscribe\", headers: { req_id }, body: { bot_id, secret } }\n\tsubReqID := p.generateReqID(\"aibot_subscribe\")\n\tsubFrame := map[string]any{\n\t\t\"cmd\":     \"aibot_subscribe\",\n\t\t\"headers\": map[string]string{\"req_id\": subReqID},\n\t\t\"body\": map[string]string{\n\t\t\t\"bot_id\": p.botID,\n\t\t\t\"secret\": p.secret,\n\t\t},\n\t}\n\tif err := p.writeJSON(subFrame); err != nil {\n\t\treturn fmt.Errorf(\"subscribe: %w\", err)\n\t}\n\n\t// Read subscribe response: { headers: { req_id }, errcode: 0, errmsg: \"ok\" }\n\tvar subResp wsFrame\n\tif err := conn.ReadJSON(&subResp); err != nil {\n\t\treturn fmt.Errorf(\"subscribe response: %w\", err)\n\t}\n\tif subResp.ErrCode == nil || *subResp.ErrCode != 0 {\n\t\terrCode := 0\n\t\tif subResp.ErrCode != nil {\n\t\t\terrCode = *subResp.ErrCode\n\t\t}\n\t\treturn fmt.Errorf(\"subscribe failed: errcode=%d errmsg=%s\", errCode, subResp.ErrMsg)\n\t}\n\tslog.Info(\"wecom-ws: subscribed successfully\", \"bot_id\", p.botID)\n\tp.missedPong.Store(0)\n\n\t// Start heartbeat goroutine","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wecom/websocket.go#L220-L256","documentation":"After dialing, runConnection sends a subscribe frame containing bot_id and secret to register the bot on the WebSocket; this error wraps a failure writing that frame to the socket. writeJSON fails when the connection is already broken (write to closed conn, broken pipe) or serialization fails.","triggerScenarios":"The underlying conn write fails right after dial — server closed the connection immediately, TLS/network issue between dial and subscribe, or the context was canceled mid-write.","commonSituations":"WeCom gateway rejecting/closing connections from blocked IPs; very unstable network where the socket dies within milliseconds; shutdown racing with connect (p.ctx canceled during write).","solutions":["Check the wrapped cause: broken pipe/reset means the server dropped the socket — verify bot_id/secret are valid so the server doesn't reject immediately.","Re-check connectivity and firewall rules to the wss endpoint.","If 'context canceled', ignore — the platform is shutting down.","Let connectLoop retry; if it recurs every attempt, capture a packet trace or check WeCom service status."],"exampleFix":"null","handlingStrategy":"retry","validationCode":"if err := p.conn.Ping(); err != nil { reconnect() } // socket liveness check before writing","typeGuard":"null","tryCatchPattern":"if err := platform.Start(ctx); err != nil {\n\tif errors.Is(err, context.Canceled) { return nil }\n\tretryWithBackoff(err)\n}","preventionTips":["Verify credentials are valid so the server doesn't drop the socket immediately","Keep ctx cancellation handling distinct from real network failures","Monitor for repeated subscribe write failures as a sign of IP blocking"],"tags":["wecom","websocket","subscribe","network"],"backgroundTag":"broken-pipe","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"}