chenhg5/cc-connect · error

qq: invalid session key %q

Error message

qq: invalid session key %q

What it means

ReconstructReplyCtx returns this when the supplied sessionKey is not a valid QQ session key. Valid formats are `qq:{userID}`, `qq:{groupID}:{userID}`, or `qq:g:{groupID}`; anything not starting with the `qq:` prefix or with fewer than 2 colon-separated parts is rejected. This guards the reply-context reconstruction path against malformed or foreign session keys.

Source

Thrown at platform/qq/qq.go:649

	var result map[string]any
	_ = json.Unmarshal(apiResp.Data, &result)
	return result, nil
}

// ── Helpers ─────────────────────────────────────────────────────

type replyContext struct {
	messageType string // "private" or "group"
	userID      int64
	groupID     int64
	messageID   int32
}

func (p *Platform) ReconstructReplyCtx(sessionKey string) (any, error) {
	// qq:{userID}, qq:{groupID}:{userID} or qq:g:{groupID}
	parts := strings.SplitN(sessionKey, ":", 3)
	if len(parts) < 2 || parts[0] != "qq" {
		return nil, fmt.Errorf("qq: invalid session key %q", sessionKey)
	}
	if len(parts) == 3 {
		if parts[1] == "g" {
			gid, _ := strconv.ParseInt(parts[2], 10, 64)
			return &replyContext{messageType: "group", groupID: gid}, nil
		}
		gid, _ := strconv.ParseInt(parts[1], 10, 64)
		uid, _ := strconv.ParseInt(parts[2], 10, 64)
		return &replyContext{messageType: "group", groupID: gid, userID: uid}, nil
	}
	uid, _ := strconv.ParseInt(parts[1], 10, 64)
	return &replyContext{messageType: "private", userID: uid}, nil
}

func (p *Platform) isAllowed(userID int64) bool {
	if p.allowFrom == "" || p.allowFrom == "*" {
		return true
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Print/log the offending sessionKey in the error and fix how it was generated or persisted.
  2. Only pass keys originally produced by this platform's session-key builder (qq:...).
  3. Namespace stored session keys by platform so QQ keys are never mixed with others.
  4. Validate the key format at persistence time (prefix check) to fail early.

Example fix

// before
ctx, err := p.ReconstructReplyCtx(key) // key may be from another platform
// after
if !strings.HasPrefix(key, "qq:") {
    return fmt.Errorf("not a qq session key: %q", key)
}
ctx, err := p.ReconstructReplyCtx(key)
Defensive patterns

Strategy: validation

Validate before calling

// Go
func isQQSessionKey(k string) bool {
    parts := strings.SplitN(k, ":", 3)
    return len(parts) >= 2 && parts[0] == "qq"
}
// call before ReconstructReplyCtx
if !isQQSessionKey(key) { return fmt.Errorf("not a qq session key: %q", key) }

Type guard

func validQQSessionKey(k string) bool {
    p := strings.SplitN(k, ":", 3)
    return len(p) >= 2 && p[0] == "qq"
}

Try / catch

ctx, err := p.ReconstructReplyCtx(key)
if err != nil {
    // treat as foreign/corrupt key: skip or rebuild the session context
    return nil
}

Prevention

When it happens

Trigger: Passing a session key from another platform (e.g. `feishu:...`, `telegram:123`), an empty string, or a key with a missing prefix/ID component to ReconstructReplyCtx.

Common situations: Storing session keys across multiple platforms in one store and replaying a non-QQ key; truncating a key before persistence; schema/serialization change dropping the prefix; hand-editing session data.

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/53820032e0e2fd90. Report an issue: GitHub.