{"record":{"id":"b99036c04328ef91","repo":"chenhg5/cc-connect","slug":"cloud-web-no-reply-context-for-session-q","errorCode":null,"errorMessage":"cloud_web: no reply context for session %q","messagePattern":"cloud_web: no reply context for session %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/cloud-web/cloudweb.go","lineNumber":523,"sourceCode":"\tif !p.hasCap(capCard) {\n\t\treturn p.Reply(ctx, rc, card.RenderText())\n\t}\n\treturn p.sendWire(ctx, map[string]any{\n\t\t\"type\":        \"card\",\n\t\t\"session_key\": rc.SessionKey,\n\t\t\"reply_ctx\":   rc.ReplyCtx,\n\t\t\"card\":        serializeCard(card),\n\t})\n}\n\nfunc (p *Platform) ReplyCard(ctx context.Context, replyCtx any, card *core.Card) error {\n\treturn p.SendCard(ctx, replyCtx, card)\n}\n\nfunc (p *Platform) RefreshCard(ctx context.Context, sessionKey string, card *core.Card) error {\n\treplyCtx, ok := p.lookupReplyCtx(sessionKey)\n\tif !ok {\n\t\treturn fmt.Errorf(\"cloud_web: no reply context for session %q\", sessionKey)\n\t}\n\tif !p.hasCap(capCard) {\n\t\treturn p.Reply(ctx, replyContext{SessionKey: sessionKey, ReplyCtx: replyCtx}, card.RenderText())\n\t}\n\treturn p.sendWire(ctx, map[string]any{\n\t\t\"type\":        \"card\",\n\t\t\"session_key\": sessionKey,\n\t\t\"reply_ctx\":   replyCtx,\n\t\t\"card\":        serializeCard(card),\n\t})\n}\n\nfunc (p *Platform) UpdateMessage(ctx context.Context, replyCtx any, content string) error {\n\trc, err := parseReplyCtx(replyCtx)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !p.hasCap(capUpdateMessage) {","sourceCodeStart":505,"sourceCodeEnd":541,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/cloud-web/cloudweb.go#L505-L541","documentation":"RefreshCard needs a stored reply context (chat_id/message_id pairs captured when the session last replied) to know which card to update. If lookupReplyCtx finds nothing for the given sessionKey, the card cannot be refreshed and this error is returned. Cards can only be refreshed for sessions that previously produced a message.","triggerScenarios":"Calling p.RefreshCard(ctx, sessionKey, card) with a sessionKey that has never replied through this platform instance, or whose reply context was evicted/lost after restart.","commonSituations":"Streaming card updates started before the first assistant message established a reply context; process restart wiping the in-memory reply-context map while the engine still holds the old sessionKey; a session key typo or mismatched key format between agent and platform.","solutions":["Only call RefreshCard after the session has sent at least one message that captured a reply context (e.g. after the first reply)","Fall back to p.Send / SendCard for sessions without a stored context instead of refreshing","Handle the error by logging and sending a normal message card rather than an in-place update","Persist reply contexts if updates must survive restarts, or accept the loss and start a new message"],"exampleFix":"// before\nif err := p.RefreshCard(ctx, key, card); err != nil { return err }\n\n// after\nif err := p.RefreshCard(ctx, key, card); err != nil {\n    log.Warn(\"no reply ctx, sending new card\", \"err\", err)\n    return p.SendCard(ctx, fallbackCtx, card)\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := p.RefreshCard(ctx, key, card); err != nil {\n    log.Warn(\"refresh failed, sending new card\", \"err\", err)\n    return p.SendCard(ctx, freshCtx, card)\n}","preventionTips":["Only refresh cards after the session has an established reply","Fall back to sending a new message when refresh fails","Consider persisting reply contexts across restarts if streaming updates must resume"],"tags":["cloud-web","cards","session"],"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-14T05:17:10.506Z"}