From 013dab185ca790c555ab1d8860342ccb59e8ec5e Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Wed, 22 Apr 2026 13:12:57 -0700 Subject: [PATCH] ChatMessageList: remove the button if Gemini Reattach is 404 --- src/apps/chat/components/ChatMessageList.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/apps/chat/components/ChatMessageList.tsx b/src/apps/chat/components/ChatMessageList.tsx index 848e28864..397e6f89e 100644 --- a/src/apps/chat/components/ChatMessageList.tsx +++ b/src/apps/chat/components/ChatMessageList.tsx @@ -132,7 +132,7 @@ export function ChatMessageList(props: { if (!llmId) throw new Error('No model id on generator'); const { aixCreateChatGenerateContext, aixReattachContent_DMessage_orThrow } = await import('~/modules/aix/client/aix.client'); - await aixReattachContent_DMessage_orThrow( + const result = await aixReattachContent_DMessage_orThrow( llmId, generator, aixCreateChatGenerateContext('conversation', conversationId), @@ -145,6 +145,14 @@ export function ChatMessageList(props: { }, isDone /* messageComplete */, true /* touch */); }, ); + + // Manual reattach is one-shot: on failure (e.g. upstream 404 from expired or already-consumed handle), + // drop the upstreamHandle so the Resume button doesn't keep luring the user into the same error. + // On 'aborted' we keep it so the user can try again later; on 'completed' the reassembler already cleared it. + if (result.outcome === 'failed' && result.generator?.upstreamHandle) + conversationHandler.messageEdit(messageId, { + generator: { ...result.generator, upstreamHandle: undefined }, + }, false /* messageComplete */, true /* touch */); }, [conversationHandler, conversationId]);