From 02abe3c821b811582f9cf4b572234d997fe297c3 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Thu, 23 Jul 2026 15:56:28 +0800 Subject: [PATCH] fix(gui): todo-row guards valid-JSON invalid-shape args before dereferencing null roots, non-object roots, and null array items (retained verbatim on a rejected tool/call) now take the documented generic-summary fallback instead of throwing into the row error boundary. --- .../client/ui-conversation/tests/todo-panel.spec.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/client/ui-conversation/tests/todo-panel.spec.tsx b/packages/client/ui-conversation/tests/todo-panel.spec.tsx index 761cb4dfd3..d3c5b93ecf 100644 --- a/packages/client/ui-conversation/tests/todo-panel.spec.tsx +++ b/packages/client/ui-conversation/tests/todo-panel.spec.tsx @@ -113,6 +113,16 @@ describe('TodoRow', () => { expect(openDetails).toHaveBeenCalledTimes(1) }) + it.each([ + { label: 'null root', argsRaw: 'null' }, + { label: 'non-object root', argsRaw: '42' }, + { label: 'null items', argsRaw: '{"todos":[null]}' }, + ])('falls back to the generic summary on valid JSON with an invalid shape ($label)', ({ argsRaw }) => { + render() + // No throw, and the generic others summary carries the raw args verbatim. + expect(screen.getByText(`todo_write · ${argsRaw}`)).toBeTruthy() + }) + it('window-truncated result (call head lost) falls back to the callId summary', () => { render() expect(screen.getByText('todo_write · c1')).toBeTruthy()