davila7/claude-code-templates · error

Failed to load timeline

Error message

Failed to load timeline

What it means

Catch-all HTTP 500 for the teams dashboard timeline route: session parsed successfully but slicing/paginating events threw — usually a malformed event array or serialization error (circular structure, BigInt).

Source

Thrown at cli-tool/src/teams-dashboard.js:715

    this.app.get('/api/sessions/:id/timeline', async (req, res) => {
      try {
        const session = await this.parseFullSession(req.params.id);
        if (!session) return res.status(404).json({ error: 'Session not found' });

        const page = parseInt(req.query.page) || 0;
        const pageSize = parseInt(req.query.pageSize) || 50;
        const start = page * pageSize;
        const events = session.events.slice(start, start + pageSize);

        res.json({
          events,
          total: session.events.length,
          page,
          pageSize,
          hasMore: start + pageSize < session.events.length
        });
      } catch (error) {
        res.status(500).json({ error: 'Failed to load timeline' });
      }
    });

    // Communications
    this.app.get('/api/sessions/:id/communications', async (req, res) => {
      try {
        const session = await this.parseFullSession(req.params.id);
        if (!session) return res.status(404).json({ error: 'Session not found' });

        res.json({
          communications: session.communications,
          count: session.communications.length
        });
      } catch (error) {
        res.status(500).json({ error: 'Failed to load communications' });
      }
    });

View on GitHub (pinned to a0851ed10c)

Solutions

  1. Test the same session via /api/sessions/:id to isolate parsing vs serialization
  2. Check parser output shape for the session; remove/repair the session file
  3. Restart dashboard to re-parse

Example fix

// before
const events = session.events.slice(start, start + pageSize);
// after
const events = (session.events || []).slice(start, start + pageSize);
Defensive patterns

Strategy: try-catch

Validate before calling

const hasEvents = await fetch(`/api/sessions/${id}`).then(r => r.json()).then(s => Array.isArray(s.events));

Type guard

const hasEventArray = (s) => Array.isArray(s?.events);

Try / catch

try { const t = await getTimeline(id, page); } catch { fallbackToSessionDetail(id); }

Prevention

When it happens

Trigger: GET /api/sessions/:id/timeline?page=N&pageSize=M where session.events is undefined or contains non-serializable values; also parseInt failures on NaN inputs fall back safely, so the throw is data-driven.

Common situations: Parser produced an events array with unexpected shapes after an upgrade; very large sessions hitting JSON serialization limits.

Related errors


AI-assisted analysis of davila7/claude-code-templates@a0851ed10c (2026-08-28). Data as JSON: /api/errors/74f50a3038a28710. Report an issue: GitHub.