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
- Print/log the offending sessionKey in the error and fix how it was generated or persisted.
- Only pass keys originally produced by this platform's session-key builder (qq:...).
- Namespace stored session keys by platform so QQ keys are never mixed with others.
- 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
- Namespace persisted session keys by platform so only qq: keys reach this API.
- Round-trip test keys through the session-key builder before storing them.
- Never truncate or hand-edit stored session keys.
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
- bridge: cannot determine adapter from session key %q
- bridge: invalid session key %q
- platform %q not found for session %q
- invalid source session key: %w
- invalid session key format: %q
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/53820032e0e2fd90.
Report an issue: GitHub.