{"record":{"id":"06a39f583f04227e","repo":"chenhg5/cc-connect","slug":"wps-xiezuo-invalid-session-key-q","errorCode":null,"errorMessage":"wps-xiezuo: invalid session key %q","messagePattern":"wps-xiezuo: invalid session key %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wps-xiezuo/wpsxiezuo.go","lineNumber":1009,"sourceCode":"\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\trespBody, _ := io.ReadAll(resp.Body)\n\t\treturn fmt.Errorf(\"delete reaction failed: status=%d body=%s\", resp.StatusCode, string(respBody))\n\t}\n\treturn nil\n}\n\n// --- Optional interface: ReplyContextReconstructor ---\n\nfunc (p *Platform) ReconstructReplyCtx(sessionKey string) (any, error) {\n\t// Formats:\n\t//   wps-xiezuo:{company_id}:{chat_id}             - group or legacy P2P\n\t//   wps-xiezuo:{company_id}:{chat_id}:{sender_id} - P2P, user-scoped\n\tparts := strings.SplitN(sessionKey, \":\", 4)\n\tif len(parts) < 3 || parts[0] != \"wps-xiezuo\" {\n\t\treturn nil, fmt.Errorf(\"wps-xiezuo: invalid session key %q\", sessionKey)\n\t}\n\trc := replyContext{\n\t\tChatID:    parts[2],\n\t\tCompanyID: parts[1],\n\t}\n\tif len(parts) == 4 {\n\t\trc.ChatType = \"p2p\"\n\t\trc.SenderID = parts[3]\n\t}\n\treturn rc, nil\n}\n\n// --- Optional interface: TypingIndicator ---\n\nfunc (p *Platform) StartTyping(ctx context.Context, rctx any) (stop func()) {\n\trc, ok := rctx.(replyContext)\n\tif !ok {\n\t\treturn func() {}","sourceCodeStart":991,"sourceCodeEnd":1027,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wps-xiezuo/wpsxiezuo.go#L991-L1027","documentation":"ReconstructReplyCtx parses a session key expected in the format \"wps-xiezuo:{company_id}:{chat_id}\" (optionally \":{sender_id}\"); if the key has fewer than 3 colon-separated parts or doesn't start with \"wps-xiezuo\", it returns this error.","triggerScenarios":"Passing a session key from a different platform, a manually constructed key, a key with missing fields, or a truncated/corrupted stored key into ReconstructReplyCtx.","commonSituations":"Persisted session keys from an older format being replayed after an upgrade; copying a key from another platform adapter; trimming the key string incorrectly before calling.","solutions":["Print the full sessionKey and compare with the documented format \"wps-xiezuo:{company_id}:{chat_id}[:{sender_id}]\"","Ensure the key originates from this platform's reply-context generation, not another adapter","Fix the persistence layer storing truncated keys","Guard with a prefix check (strings.HasPrefix(key, \"wps-xiezuo:\")) before calling"],"exampleFix":"// before\nrc, err := p.ReconstructReplyCtx(storedKey) // storedKey = \"xiezuo:123:456\"\n// after\nif !strings.HasPrefix(storedKey, \"wps-xiezuo:\") { /* regenerate or skip */ }\nrc, err := p.ReconstructReplyCtx(storedKey)","handlingStrategy":"validation","validationCode":"func isValidXiezuoSessionKey(k string) bool { return strings.HasPrefix(k, \"wps-xiezuo:\") && len(strings.SplitN(k, \":\", 4)) >= 3 }","typeGuard":null,"tryCatchPattern":"rc, err := p.ReconstructReplyCtx(key); if err != nil && strings.Contains(err.Error(), \"invalid session key\") { slog.Warn(\"skipping malformed session key\", \"key\", key); return }","preventionTips":["Only build session keys via the platform's own context generation","Include a version prefix in persisted session keys","Validate keys at persistence time, not just at read time"],"tags":["session-key","parsing","wps"],"backgroundTag":"invalid-argument-format","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}