{"record":{"id":"ed49bfea74c454bd","repo":"chenhg5/cc-connect","slug":"s-no-tracked-card-messageid-for-session-q","errorCode":null,"errorMessage":"%s: no tracked card messageID for session %q","messagePattern":"(.+?): no tracked card messageID for session %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platform/feishu/card.go","lineNumber":64,"sourceCode":"\n\tif !p.noReplyToTrigger && p.shouldReplyInThread(rc) {\n\t\treturn p.ReplyCard(ctx, rctx, card)\n\t}\n\n\tcardJSON := renderCard(card, rc.sessionKey)\n\treturn p.createMessage(ctx, rc.chatID, larkim.MsgTypeInteractive, cardJSON, \"send card\")\n}\n\n// RefreshCard updates a previously rendered card in-place using the Patch API.\n// It looks up the messageID stored from the most recent card action callback\n// for the given session key and patches that message with the new card content.\nfunc (p *interactivePlatform) RefreshCard(ctx context.Context, sessionKey string, card *core.Card) error {\n\tp.cardActionMsgMu.Lock()\n\tmsgID := p.cardActionMsgIDs[sessionKey]\n\tp.cardActionMsgMu.Unlock()\n\n\tif msgID == \"\" {\n\t\treturn fmt.Errorf(\"%s: no tracked card messageID for session %q\", p.tag(), sessionKey)\n\t}\n\n\tcardJSON := renderCard(card, sessionKey)\n\treq := larkim.NewPatchMessageReqBuilder().\n\t\tMessageId(msgID).\n\t\tBody(larkim.NewPatchMessageReqBodyBuilder().\n\t\t\tContent(cardJSON).\n\t\t\tBuild()).\n\t\tBuild()\n\treturn p.withTransientRetry(ctx, \"refresh card\", func() error {\n\t\treturn p.withFreshTenantAccessTokenRetry(ctx, \"refresh card\", func(client *lark.Client, options ...larkcore.RequestOptionFunc) error {\n\t\t\tresp, err := client.Im.Message.Patch(ctx, req, options...)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"%s: refresh card: %w\", p.tag(), err)\n\t\t\t}\n\t\t\tif !resp.Success() {\n\t\t\t\treturn fmt.Errorf(\"%s: refresh card code=%d msg=%s\", p.tag(), resp.Code, resp.Msg)\n\t\t\t}","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/card.go#L46-L82","documentation":"feishu: no tracked card messageID for session is raised in RefreshCard when there is no recorded message ID for the given session key, so the existing card cannot be patched in place. The adapter tracks interactive-card message IDs (from card action callbacks) to update cards later. Without a tracked ID, refresh is impossible and a fresh send is the fallback.","triggerScenarios":"RefreshCard (card.go:64) called with a sessionKey never seen in a card action callback, a typo'd session key, or after adapter restart cleared the in-memory cardActionMsgIDs map.","commonSituations":"Bot restarted between card render and refresh (map is memory-only); user clicked a card from a different session than expected; card was not interactive so no message ID was ever recorded.","solutions":["Fall back to SendCard with the session's chat ID when RefreshCard reports no tracked message","Persist cardActionMsgIDs across restarts if refresh must survive restarts","Verify the sessionKey matches the one used in the card action callback","Ensure the original message was sent as an interactive card (only those get tracked)"],"exampleFix":"// before\nerr := p.RefreshCard(ctx, sessionKey, card)\n// after\nif err := p.RefreshCard(ctx, sessionKey, card); err != nil {\n    if rc, ok := sessionReplyCtx(sessionKey); ok {\n        err = p.SendCard(ctx, rc, card) // fallback: fresh message\n    }\n}","handlingStrategy":"fallback","validationCode":"p.cardActionMsgMu.Lock(); _, tracked := p.cardActionMsgIDs[sessionKey]; p.cardActionMsgMu.Unlock()\nif !tracked { return errors.New(\"no tracked card; use SendCard instead\") }","typeGuard":null,"tryCatchPattern":"if err := p.RefreshCard(ctx, sessionKey, card); err != nil {\n    log.Warn(\"card refresh unavailable; sending fresh card\", \"err\", err)\n    return p.SendCard(ctx, rc, card)\n}","preventionTips":["Persist card message IDs if refresh must survive restarts","Confirm the session key before invoking RefreshCard","Only refresh messages that were originally interactive cards"],"tags":["feishu","state-tracking","card"],"backgroundTag":"record-not-found","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"}