chenhg5/cc-connect · error

wecom-ws: chatID is empty, cannot send proactive message

Error message

wecom-ws: chatID is empty, cannot send proactive message

What it means

Guard in wecom-ws Send (proactive aibot_send_msg path): the reply context is valid but its chatID field is empty, so there is no conversation to address a follow-up/cron message to. This typically happens when the context was built from a callback payload that lacked the chat identifier, or a session key was reconstructed without a chatID segment.

Source

Thrown at platform/wecom/websocket.go:509

		return err
	}
	slog.Debug("wecom-ws: reply sent", "user", rc.userID, "len", len(content))
	return nil
}

// Send sends a proactive message via aibot_send_msg (markdown format).
// Used for follow-up messages and cron-triggered messages where no req_id is available.
// Markdown is natively supported.
func (p *WSPlatform) Send(ctx context.Context, rctx any, content string) error {
	rc, ok := rctx.(wsReplyContext)
	if !ok {
		return fmt.Errorf("wecom-ws: invalid reply context type %T", rctx)
	}
	if content == "" {
		return nil
	}
	if rc.chatID == "" {
		return fmt.Errorf("wecom-ws: chatID is empty, cannot send proactive message")
	}

	chunks := splitByBytes(content, 2000)
	for i, chunk := range chunks {
		reqID := p.generateReqID("aibot_send_msg")
		frame := map[string]any{
			"cmd":     "aibot_send_msg",
			"headers": map[string]string{"req_id": reqID},
			"body": map[string]any{
				"chatid":  rc.chatID,
				"msgtype": "markdown",
				"markdown": map[string]string{
					"content": chunk,
				},
			},
		}
		if err := p.writeAndWaitAck(ctx, frame, reqID); err != nil {
			slog.Error("wecom-ws: send failed", "user", rc.userID, "chunk", i, "error", err)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify the callback handler stores chatID into wsReplyContext before invoking Send
  2. Check that the session key used to rebuild the context contains the chatID component (wecom:{chatID}:{userID})
  3. Skip and log the dropped message instead of retrying — the missing ID is not transient
  4. Fall back to a user-addressed API path if the deployment supports it
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at platform/wecom/websocket.go:509 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/07ddf4daaf25e64c. Report an issue: GitHub.