{"record":{"id":"38f016d01a79889d","repo":"chenhg5/cc-connect","slug":"webex-cannot-reconstruct-reply-ctx-from-q","errorCode":null,"errorMessage":"webex: cannot reconstruct reply ctx from %q","messagePattern":"webex: cannot reconstruct reply ctx from %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/webex/webex_reply.go","lineNumber":116,"sourceCode":"}\n\n// SendFile implements core.FileSender.\nfunc (p *Platform) SendFile(ctx context.Context, replyCtx any, file core.FileAttachment) error {\n\trc, err := asReplyContext(replyCtx)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn p.client.PostFile(ctx, rc.roomID, &downloadedFile{\n\t\tData: file.Data, MimeType: file.MimeType, FileName: file.FileName,\n\t})\n}\n\n// ReconstructReplyCtx implements core.ReplyContextReconstructor for cron jobs.\n// Session key format is \"webex:{roomID}:{personID}\".\nfunc (p *Platform) ReconstructReplyCtx(sessionKey string) (any, error) {\n\tparts := strings.SplitN(sessionKey, \":\", 3)\n\tif len(parts) < 2 || parts[0] != \"webex\" {\n\t\treturn nil, fmt.Errorf(\"webex: cannot reconstruct reply ctx from %q\", sessionKey)\n\t}\n\trc := replyContext{roomID: parts[1]}\n\tif len(parts) == 3 {\n\t\trc.personID = parts[2]\n\t}\n\treturn rc, nil\n}\n\n// FormattingInstructions implements core.FormattingInstructionProvider.\nfunc (p *Platform) FormattingInstructions() string {\n\treturn \"Webex supports standard Markdown (bold, italic, lists, code blocks, links). Use it freely.\"\n}\n\n// Compile-time interface conformance checks.\nvar (\n\t_ core.Platform                      = (*Platform)(nil)\n\t_ core.ImageSender                   = (*Platform)(nil)\n\t_ core.FileSender                    = (*Platform)(nil)","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/webex/webex_reply.go#L98-L134","documentation":"ReconstructReplyCtx parses a persisted session key expected to be in the form \"webex:{roomID}:{personID}\" so cron jobs can rebuild a reply context. It throws this when the key does not have the \"webex\" prefix or lacks at least a roomID segment. This is a defensive check against corrupted or foreign session keys.","triggerScenarios":"Called with a sessionKey produced by another platform adapter, a manually edited/stale key, or a string missing the roomID field after the second colon-split part.","commonSituations":"Cron job config pointing at a session key copied from a different platform (e.g. \"feishu:...\"); storage migration losing the key prefix; an empty or truncated key restored from backup.","solutions":["Check the session key stored for the cron job; it must start with \"webex:\" and contain the roomID.","Correct the session key in your config/state to the \"webex:{roomID}:{personID}\" format.","If migrating keys from another platform, recreate the session through the webex platform instead of reusing the key.","Log the offending key value to trace which component wrote an invalid key."],"exampleFix":"// before\nctx, err := p.ReconstructReplyCtx(\"feishu:ou_123\") // wrong prefix\n// after\nctx, err := p.ReconstructReplyCtx(\"webex:Y2lzY29zcGFyazovL3VzL1JPT00:personID\")","handlingStrategy":"validation","validationCode":"func validWebexSessionKey(k string) bool {\n\tparts := strings.SplitN(k, \":\", 3)\n\treturn len(parts) >= 2 && parts[0] == \"webex\" && parts[1] != \"\"\n}","typeGuard":"func isWebexReplyCtx(v any) bool {\n\t_, ok := v.(replyContext)\n\treturn ok\n}","tryCatchPattern":"rc, err := p.ReconstructReplyCtx(key)\nif err != nil {\n\treturn fmt.Errorf(\"cron: bad session key %q: %w\", key, err)\n}","preventionTips":["Never hand-edit session keys; generate them via the platform","Prefix-check keys before persisting them for cron jobs","Validate keys after restoring from backups/migrations"],"tags":["webex","session","parsing","validation"],"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"}