diff --git a/packages/cli/src/ui/components/AnsiOutput.test.tsx b/packages/cli/src/ui/components/AnsiOutput.test.tsx
index 758361be0a..6331c149a8 100644
--- a/packages/cli/src/ui/components/AnsiOutput.test.tsx
+++ b/packages/cli/src/ui/components/AnsiOutput.test.tsx
@@ -156,4 +156,30 @@ describe('', () => {
expect(lastFrame()).toBeDefined();
unmount();
});
+
+ describe('robustness', () => {
+ it('does NOT crash when data is undefined', async () => {
+ const { lastFrame, unmount } = await render(
+ ,
+ );
+ expect(lastFrame({ allowEmpty: true }).trim()).toBe('');
+ unmount();
+ });
+
+ it('does NOT crash when data is an object but not an array', async () => {
+ const { lastFrame, unmount } = await render(
+ ,
+ );
+ expect(lastFrame({ allowEmpty: true }).trim()).toBe('');
+ unmount();
+ });
+ });
});
diff --git a/packages/cli/src/ui/components/AnsiOutput.tsx b/packages/cli/src/ui/components/AnsiOutput.tsx
index a1b30b0856..617740d4ad 100644
--- a/packages/cli/src/ui/components/AnsiOutput.tsx
+++ b/packages/cli/src/ui/components/AnsiOutput.tsx
@@ -35,14 +35,16 @@ export const AnsiOutputText: React.FC = ({
? Math.min(availableHeightLimit, maxLines)
: (availableHeightLimit ?? maxLines ?? DEFAULT_HEIGHT);
- const lastLines = disableTruncation
- ? data
- : numLinesRetained === 0
- ? []
- : data.slice(-numLinesRetained);
+ const lastLines = Array.isArray(data)
+ ? disableTruncation
+ ? data
+ : numLinesRetained === 0
+ ? []
+ : data.slice(-numLinesRetained)
+ : [];
return (
- {lastLines.map((line: AnsiLine, lineIndex: number) => (
+ {(lastLines as AnsiLine[]).map((line: AnsiLine, lineIndex: number) => (
diff --git a/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx b/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx
index 92791328be..4abe79345b 100644
--- a/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx
+++ b/packages/cli/src/ui/components/messages/ToolResultDisplay.tsx
@@ -158,7 +158,7 @@ export const ToolResultDisplay: React.FC = ({
terminalWidth={childWidth}
/>
);
- } else {
+ } else if (Array.isArray(contentData)) {
const shouldDisableTruncation =
isAlternateBuffer ||
(availableTerminalHeight === undefined && maxLines === undefined);
@@ -175,6 +175,15 @@ export const ToolResultDisplay: React.FC = ({
disableTruncation={shouldDisableTruncation}
/>
);
+ } else if (typeof contentData === 'object' && contentData !== null) {
+ // Render as JSON for other non-null objects
+ content = (
+
+ {JSON.stringify(contentData, null, 2)}
+
+ );
+ } else {
+ content = null;
}
// Final render based on session mode