Browse Source

Fix: Cannot read properties of undefined error

Fixed JavaScript error when loading schedules:

Issue: s.messages[0] tried to access index before optional chaining
Fix: Use s.messages?.[0]?.content with proper optional chaining

Also added:
- Fallback to 'N/A' for all fields if undefined
- Debug logging to see Letta API response structure
- More defensive filtering with optional chaining
- Fallback to s.message if s.messages doesn't exist

Error message: 'Cannot read properties of undefined (reading "0")'
Root cause: Incorrect optional chaining syntax

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta <noreply@letta.com>
Cameron Pfiffer 3 months ago
parent
commit
0071af3e1f
1 changed files with 12 additions and 11 deletions
  1. 12 11
      dashboard.html

+ 12 - 11
dashboard.html

@@ -614,29 +614,30 @@
                 }
                 
                 const data = await response.json();
-                const schedules = data.scheduled_messages || [];
+                console.log('Letta API response:', data); // Debug log
+                const schedules = data.scheduled_messages || data.schedules || data || [];
                 
                 // Split into one-time and recurring
-                const onetime = schedules.filter(s => s.schedule.type === 'one-time');
-                const recurring = schedules.filter(s => s.schedule.type === 'recurring');
+                const onetime = schedules.filter(s => s.schedule?.type === 'one-time');
+                const recurring = schedules.filter(s => s.schedule?.type === 'recurring');
 
                 onetimeBody.innerHTML = onetime.length ? onetime.map(s => `
                     <tr>
-                        <td class="mono">${s.id.substring(0, 8)}...</td>
-                        <td class="mono">${s.agent_id}</td>
-                        <td>${fromUnixMs(s.next_scheduled_at)}</td>
-                        <td>${truncate(s.messages[0]?.content || '', 50)}</td>
+                        <td class="mono">${s.id?.substring(0, 8) || 'N/A'}...</td>
+                        <td class="mono">${s.agent_id || 'N/A'}</td>
+                        <td>${s.next_scheduled_at ? fromUnixMs(s.next_scheduled_at) : 'N/A'}</td>
+                        <td>${truncate(s.messages?.[0]?.content || s.message || 'N/A', 50)}</td>
                         <td><button class="danger sm" onclick="deleteSchedule('${s.id}')">Delete</button></td>
                     </tr>
                 `).join('') : '<tr><td colspan="5" class="empty">No one-time schedules</td></tr>';
 
                 recurringBody.innerHTML = recurring.length ? recurring.map(s => `
                     <tr>
-                        <td class="mono">${s.id.substring(0, 8)}...</td>
-                        <td class="mono">${s.agent_id}</td>
-                        <td class="mono">${s.schedule.cron_expression}</td>
+                        <td class="mono">${s.id?.substring(0, 8) || 'N/A'}...</td>
+                        <td class="mono">${s.agent_id || 'N/A'}</td>
+                        <td class="mono">${s.schedule?.cron_expression || 'N/A'}</td>
                         <td>UTC</td>
-                        <td>${truncate(s.messages[0]?.content || '', 50)}</td>
+                        <td>${truncate(s.messages?.[0]?.content || s.message || 'N/A', 50)}</td>
                         <td>${s.next_scheduled_at ? fromUnixMs(s.next_scheduled_at) : 'Never'}</td>
                         <td><button class="danger sm" onclick="deleteSchedule('${s.id}')">Delete</button></td>
                     </tr>