From 673a61edc82d9545366f3fe50788295af13b5ce1 Mon Sep 17 00:00:00 2001 From: Harry Yep Date: Tue, 30 Jun 2026 17:24:24 +0800 Subject: [PATCH] fix(desktop): match renamed useClientLookup out-of-bounds throw in MessageRenderBoundary @assistant-ui/store renamed its index-out-of-bounds throw from tapClientLookup/tapClientResource to useClientLookup in the 0.14 upgrade, so the boundary's /tapClient.../ filter stopped matching and re-threw the transient session-switch and reconnect race to root, blanking the app. broaden the regex to accept the new prefix (keeping the old one for older store versions) and point the test at the real message so it exercises the live path instead of the dead string. --- .../components/assistant-ui/message-render-boundary.test.tsx | 4 ++-- .../src/components/assistant-ui/message-render-boundary.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/components/assistant-ui/message-render-boundary.test.tsx b/apps/desktop/src/components/assistant-ui/message-render-boundary.test.tsx index 934f3babd1c0..8e1b70f7934f 100644 --- a/apps/desktop/src/components/assistant-ui/message-render-boundary.test.tsx +++ b/apps/desktop/src/components/assistant-ui/message-render-boundary.test.tsx @@ -13,7 +13,7 @@ function Boom({ error }: { error: Error | null }): null { return null } -const lookupError = new Error('tapClientLookup: Index 2 out of bounds (length: 2)') +const lookupError = new Error('useClientLookup: Index 2 out of bounds (length: 2)') describe('MessageRenderBoundary', () => { it('renders children when nothing throws', () => { @@ -26,7 +26,7 @@ describe('MessageRenderBoundary', () => { expect(screen.getByText('content')).toBeTruthy() }) - it('swallows the transient tapClientLookup out-of-bounds store race', () => { + it('swallows the transient useClientLookup out-of-bounds store race', () => { const spy = vi.spyOn(console, 'error').mockImplementation(() => undefined) const { container } = render( diff --git a/apps/desktop/src/components/assistant-ui/message-render-boundary.tsx b/apps/desktop/src/components/assistant-ui/message-render-boundary.tsx index 990f8c6072e4..f0fafbc4f18f 100644 --- a/apps/desktop/src/components/assistant-ui/message-render-boundary.tsx +++ b/apps/desktop/src/components/assistant-ui/message-render-boundary.tsx @@ -1,6 +1,6 @@ import { Component, type ReactNode } from 'react' -// `@assistant-ui/store`'s index-keyed child-scope lookup (`tapClientLookup`) +// `@assistant-ui/store`'s index-keyed child-scope lookup (`useClientLookup`) // throws — rather than returning undefined — when a subscriber reads an index // that the message/parts list no longer has. This races during high-frequency // store replacement (session switch mid-stream, gateway reconnect replay): a @@ -10,7 +10,7 @@ import { Component, type ReactNode } from 'react' // without a local boundary it unwinds to the root and blanks the whole app. // Upstream-tracked: assistant-ui/assistant-ui#4051, #3652. const isTransientLookupError = (error: unknown): boolean => - error instanceof Error && /tapClient(Lookup|Resource).*out of bounds/.test(error.message) + error instanceof Error && /(useClientLookup|tapClient(Lookup|Resource)).*out of bounds/.test(error.message) interface Props { // Changes whenever the message list mutates; remounting clears the caught