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

  1. Verify bot_id and bot_secret are correct — servers often close instead of returning an auth error frame.
  2. Check the wrapped read error: 'unexpected EOF' / 'connection reset' suggests server-side close; 'use of closed connection' suggests local shutdown.
  3. Confirm network stability and that no proxy is terminating websocket connections.
  4. 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

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.