chenhg5/cc-connect · error

qqbot: invalid session key %q

Error message

qqbot: invalid session key %q

What it means

ReconstructReplyCtx rebuilds a reply context from a stored session key. Valid formats are "qqbot:{group_openid}:{member_openid}" (3 parts), "qqbot:g:{group_openid}" (3 parts, group broadcast), or "qqbot:{user_openid}" (2 parts, c2c). If the key does not split into at least 2 colon-separated parts with the literal prefix "qqbot", this error is returned (platform/qqbot/qqbot.go:540).

Source

Thrown at platform/qqbot/qqbot.go:540

// Stop shuts down the platform.
func (p *Platform) Stop() error {
	if p.cancel != nil {
		p.cancel()
	}
	p.wsMu.Lock()
	defer p.wsMu.Unlock()
	if p.wsConn != nil {
		return p.wsConn.Close()
	}
	return nil
}

// ReconstructReplyCtx implements core.ReplyContextReconstructor.
// Session key format: "qqbot:{group_openid}:{member_openid}", "qqbot:g:{group_openid}" or "qqbot:{user_openid}"
func (p *Platform) ReconstructReplyCtx(sessionKey string) (any, error) {
	parts := strings.SplitN(sessionKey, ":", 3)
	if len(parts) < 2 || parts[0] != "qqbot" {
		return nil, fmt.Errorf("qqbot: invalid session key %q", sessionKey)
	}
	if len(parts) == 3 {
		if parts[1] == "g" {
			return &replyContext{
				messageType: "group",
				groupOpenID: parts[2],
				sessionKey:  sessionKey,
			}, nil
		}
		return &replyContext{
			messageType: "group",
			groupOpenID: parts[1],
			userOpenID:  parts[2],
			sessionKey:  sessionKey,
		}, nil
	}
	return &replyContext{
		messageType: "c2c",

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the stored session key starts with "qqbot:" and has the right number of colon-separated parts.
  2. If the session belongs to another platform, route it to that platform's ReconstructReplyCtx instead.
  3. Regenerate the session by messaging the bot once and using the fresh key the platform records.

Example fix

// before
rc, err := qqbotPlatform.ReconstructReplyCtx("feishu:oc_123") // invalid prefix
// after
if strings.HasPrefix(key, "qqbot:") {
    rc, err = qqbotPlatform.ReconstructReplyCtx(key)
} else {
    rc, err = feishuPlatform.ReconstructReplyCtx(key)
}
Defensive patterns

Strategy: validation

Validate before calling

func isQQBotSessionKey(key string) bool {
    parts := strings.SplitN(key, ":", 3)
    return len(parts) >= 2 && parts[0] == "qqbot"
}

Try / catch

rc, err := p.ReconstructReplyCtx(key)
if err != nil {
    slog.Warn("cannot reconstruct qqbot reply ctx", "key", core.RedactToken(key), "err", err)
    return nil // skip rather than crash
}

Prevention

When it happens

Trigger: Calling ReconstructReplyCtx with a session key from another platform (e.g. "feishu:oc_xxx"), an empty/whitespace key, a key without the "qqbot:" prefix, or a key like "qqbot" with no separator at all.

Common situations: Persisted session keys reused after switching the platform adapter; keys stored by an older version with a different format; cron/scheduled jobs referencing sessions of a different platform; hand-edited config pointing a timer at the wrong session key.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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