From d27b28abc64a8d6787fbaface4dea7b6a2c82d37 Mon Sep 17 00:00:00 2001 From: AndyMik90 Date: Sat, 21 Feb 2026 21:45:33 +0100 Subject: [PATCH] fix: resolve React Error #31 when expanding memories in Context (fixes #1879) Memory items in what_worked, what_failed, and recommendations arrays could be objects (e.g. {category, recommendation}) instead of strings when stored by Graphiti or AI agents that deviate from the expected string format. Add toSafeString() helper that safely converts any value to a renderable string, with specific handling for the {category, recommendation} object shape that caused the error. Update ParsedSessionInsight types to reflect that these arrays can contain mixed string/object items. Co-Authored-By: Claude Opus 4.6 --- .../components/context/MemoryCard.tsx | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/apps/frontend/src/renderer/components/context/MemoryCard.tsx b/apps/frontend/src/renderer/components/context/MemoryCard.tsx index 46260083..78707772 100644 --- a/apps/frontend/src/renderer/components/context/MemoryCard.tsx +++ b/apps/frontend/src/renderer/components/context/MemoryCard.tsx @@ -26,9 +26,9 @@ interface ParsedSessionInsight { spec_id?: string; session_number?: number; subtasks_completed?: string[]; - what_worked?: string[]; - what_failed?: string[]; - recommendations_for_next_session?: string[]; + what_worked?: Array>; + what_failed?: Array>; + recommendations_for_next_session?: Array>; discoveries?: { file_insights?: Array<{ path?: string; purpose?: string; changes_made?: string }>; patterns_discovered?: Array<{ pattern?: string; applies_to?: string } | string>; @@ -39,11 +39,34 @@ interface ParsedSessionInsight { why_it_worked?: string; why_it_failed?: string; }; - recommendations?: string[]; + recommendations?: Array>; changed_files?: string[]; }; } +function toSafeString(item: string | Record | unknown): string { + if (typeof item === 'string') return item; + if (item === null || item === undefined) return ''; + if (typeof item === 'object') { + const obj = item as Record; + // Handle {category, recommendation} object - the known cause of React Error #31 + if (typeof obj.category === 'string' && typeof obj.recommendation === 'string') { + return `[${obj.category}] ${obj.recommendation}`; + } + // Try other common single-field patterns + if (typeof obj.recommendation === 'string') return obj.recommendation; + if (typeof obj.text === 'string') return obj.text; + if (typeof obj.description === 'string') return obj.description; + if (typeof obj.message === 'string') return obj.message; + // Fallback: combine all string values from the object + const parts = Object.entries(obj) + .filter(([, v]) => typeof v === 'string') + .map(([k, v]) => `${k}: ${v}`); + return parts.length > 0 ? parts.join(', ') : JSON.stringify(item); + } + return String(item); +} + function parseMemoryContent(content: string): ParsedSessionInsight | null { try { return JSON.parse(content); @@ -207,7 +230,7 @@ export function MemoryCard({ memory }: MemoryCardProps) {
    {parsed.what_worked.map((item, idx) => ( - {item} + {toSafeString(item)} ))}
@@ -219,7 +242,7 @@ export function MemoryCard({ memory }: MemoryCardProps) {
    {parsed.what_failed.map((item, idx) => ( - {item} + {toSafeString(item)} ))}
@@ -261,10 +284,10 @@ export function MemoryCard({ memory }: MemoryCardProps) { />
    {parsed.recommendations_for_next_session?.map((item, idx) => ( - {item} + {toSafeString(item)} ))} {parsed.discoveries?.recommendations?.map((item, idx) => ( - {item} + {toSafeString(item)} ))}