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.
This commit is contained in:
Harry Yep 2026-06-30 17:24:24 +08:00 committed by Brooklyn Nicholson
parent 102d2d5676
commit 673a61edc8
2 changed files with 4 additions and 4 deletions

View file

@ -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(

View file

@ -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