chenhg5/cc-connect · error
subscribe response: %w
Error message
subscribe response: %w
What it means
After sending the subscribe frame, runConnection reads the subscribe response; this error wraps a ReadJSON failure while waiting for that ack. It means the socket failed or closed before a valid subscribe response frame arrived.
Source
Thrown at platform/wecom/websocket.go:244
// Send subscribe (auth) frame
// Format: { cmd: "aibot_subscribe", headers: { req_id }, body: { bot_id, secret } }
subReqID := p.generateReqID("aibot_subscribe")
subFrame := map[string]any{
"cmd": "aibot_subscribe",
"headers": map[string]string{"req_id": subReqID},
"body": map[string]string{
"bot_id": p.botID,
"secret": p.secret,
},
}
if err := p.writeJSON(subFrame); err != nil {
return fmt.Errorf("subscribe: %w", err)
}
// Read subscribe response: { headers: { req_id }, errcode: 0, errmsg: "ok" }
var subResp wsFrame
if err := conn.ReadJSON(&subResp); err != nil {
return fmt.Errorf("subscribe response: %w", err)
}
if subResp.ErrCode == nil || *subResp.ErrCode != 0 {
errCode := 0
if subResp.ErrCode != nil {
errCode = *subResp.ErrCode
}
return fmt.Errorf("subscribe failed: errcode=%d errmsg=%s", errCode, subResp.ErrMsg)
}
slog.Info("wecom-ws: subscribed successfully", "bot_id", p.botID)
p.missedPong.Store(0)
// Start heartbeat goroutine
heartCtx, heartCancel := context.WithCancel(p.ctx)
defer heartCancel()
go p.heartbeat(heartCtx, conn)
// Read loop
for {View on GitHub (pinned to 4000b2338a)
Solutions
- Verify bot_id and bot_secret are correct — servers often close instead of returning an auth error frame.
- Check the wrapped read error: 'unexpected EOF' / 'connection reset' suggests server-side close; 'use of closed connection' suggests local shutdown.
- Confirm network stability and that no proxy is terminating websocket connections.
- Let connectLoop retry; escalate if subscribe never succeeds across retries.
Example fix
null
Defensive patterns
Strategy: retry
Validate before calling
resp := authProbe(botID, secret) // test credentials against a lightweight WeCom token API before starting ws mode
if resp.failed { return errors.New("invalid wecom credentials") } Type guard
null
Try / catch
err := platform.Start(ctx)
if err != nil && strings.Contains(err.Error(), "subscribe response") {
// likely server-side close: re-validate credentials, then retry
validateCredentials(); retryWithBackoff(err)
} Prevention
- Validate bot_id/bot_secret against the token API before ws connect
- Watch for servers that close instead of acking bad credentials
- Avoid proxies that terminate websocket handshakes mid-stream
When it happens
Trigger: The server closes the connection (invalid credentials, immediate reject), a read timeout/network drop occurs, or the context is canceled while blocked in ReadJSON.
Common situations: Wrong bot_id/bot_secret causing the server to disconnect instead of acking; WeCom endpoint closing idle or unauthenticated sockets quickly; network middleboxes killing the connection during handshake.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/0087d22d2368d9fa.
Report an issue: GitHub.