{"record":{"id":"a53b99a51fe748b1","repo":"chenhg5/cc-connect","slug":"weibo-not-connected","errorCode":null,"errorMessage":"weibo: not connected","messagePattern":"weibo: not connected","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weibo/weibo.go","lineNumber":631,"sourceCode":"\t\t\t\t\tFileName: fname,\n\t\t\t\t\tSource:   &inputSource{Type: \"base64\", MediaType: mime, Data: b64},\n\t\t\t\t}},\n\t\t\t}},\n\t\t},\n\t}\n\tslog.Debug(p.tag()+\": sending file\", \"to\", rc.fromUserID, \"name\", fname, \"size\", len(file.Data))\n\treturn p.writeWS(env)\n}\n\nfunc (p *Platform) writeWS(data any) error {\n\t// gorilla/websocket only allows one concurrent writer; wsMu must guard the\n\t// full WriteJSON call (pingLoop already follows this pattern), otherwise\n\t// concurrent sendMessage / SendImage / SendFile calls interleave frames\n\t// on the wire.\n\tp.wsMu.Lock()\n\tdefer p.wsMu.Unlock()\n\tif p.ws == nil {\n\t\treturn fmt.Errorf(\"weibo: not connected\")\n\t}\n\tif err := p.ws.WriteJSON(data); err != nil {\n\t\treturn fmt.Errorf(\"weibo: ws send: %w\", err)\n\t}\n\treturn nil\n}\n\n// --- Helpers ---\n\nfunc (p *Platform) tag() string { return p.name }\n\nfunc (p *Platform) isDuplicate(msgID string) bool {\n\tp.seenMu.Lock()\n\tdefer p.seenMu.Unlock()\n\tif _, ok := p.seen[msgID]; ok {\n\t\treturn true\n\t}\n\tif len(p.seen) >= maxSeenMessages {","sourceCodeStart":613,"sourceCodeEnd":649,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weibo/weibo.go#L613-L649","documentation":"writeWS is the single serialized entry point for sending JSON frames over the Weibo WebSocket. It takes the mutex, then checks p.ws; if the connection was never established or has been closed/replaced, p.ws is nil and it returns 'weibo: not connected' instead of dereferencing nil. It surfaces a lifecycle problem: the platform is not currently online, so sendMessage, SendImage and SendFile all fail.","triggerScenarios":"Calling sendMessage/SendImage/SendFile before Platform.Start finished connecting; after the WebSocket dropped and reconnect is still in progress; after Stop was called; network outage where the ping loop has not yet re-established p.ws.","commonSituations":"Queued outgoing messages flushed during a network blip; a bot replying to an incoming message that arrived just as the socket closed; startup ordering where a cron/timer fires before the connection is up.","solutions":["Retry after a short delay, giving the adapter's reconnect loop time to re-establish p.ws","Check connection state / platform health before sending (e.g. via doctor or a readiness flag)","Ensure Start() completes successfully before invoking any send API","If persistently disconnected, verify network/proxy and Weibo endpoint reachability and restart the daemon"],"exampleFix":"if err := p.writeWS(env); err != nil {\n    if strings.Contains(err.Error(), \"not connected\") {\n        time.Sleep(reconnectBackoff)\n        return p.writeWS(env) // retry after reconnect\n    }\n    return err\n}","handlingStrategy":"retry","validationCode":"if p == nil || !p.IsConnected() { // readiness check before sending\n    return errors.New(\"weibo: platform not ready\")\n}","typeGuard":null,"tryCatchPattern":"err := p.writeWS(env)\nif errors.Is(err, errNotConnected) {\n    select {\n    case <-time.After(backoff):\n    case <-ctx.Done():\n        return ctx.Err()\n    }\n    return p.writeWS(env)\n}","preventionTips":["Start the platform and wait for a connected signal before dispatching messages","Use exponential backoff retries for transient disconnections","Monitor connection health (ping loop) and alert on prolonged disconnection","Queue outbound messages while offline and flush on reconnect"],"tags":["weibo","websocket","connection-state"],"backgroundTag":"connection-refused","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}