davila7/claude-code-templates · error

Failed to fetch analytics

Error message

Failed to fetch analytics

What it means

HTTP 500 wrapper thrown by the catch block of GET /api/conversations/:id/analytics when parsing or analyzing the conversation file fails downstream (e.g. conversationAnalyzer.getParsedConversation on the file path). The original error message is echoed in the response body's message field.

Source

Thrown at cli-tool/src/chats-mobile.js:792

            totalSkills: componentsUsed.skills.length
          },

          // Optimization tips
          optimizationTips: optimizationTips,

          // Metadata
          conversationId: conversationId,
          project: conversation.project || 'Unknown',
          timestamp: new Date().toISOString()
        };

        res.json({
          success: true,
          analytics: analytics
        });
      } catch (error) {
        console.error('Error fetching conversation analytics:', error);
        res.status(500).json({
          error: 'Failed to fetch analytics',
          message: error.message
        });
      }
    });

    // Serve the mobile chats page as default
    this.app.get('/', (req, res) => {
      res.sendFile(path.join(__dirname, 'analytics-web', 'chats_mobile.html'));
    });

    // Fallback for any other routes (but not for API or static files)
    this.app.get('*', (req, res) => {
      // Don't redirect API calls or static files
      if (req.path.startsWith('/api/') || 
          req.path.startsWith('/services/') || 
          req.path.startsWith('/components/') || 
          req.path.startsWith('/assets/')) {

View on GitHub (pinned to a0851ed10c)

Solutions

  1. Read the server console output — 'Error fetching conversation analytics:' logs the underlying error.message which pinpoints the cause
  2. Confirm conversation.filePath exists and is readable (ls + cat a few lines of the JSONL)
  3. If the file is truncated/corrupted, remove it or rescan so the in-memory index drops the stale entry
  4. Update the chats-mobile package if the analyzer is behind the current Claude Code conversation format

Example fix

// before
const r = await fetch(`/api/conversations/${id}/analytics`);
const data = await r.json(); // { error: 'Failed to fetch analytics' }
// after
const r = await fetch(`/api/conversations/${encodeURIComponent(id)}/analytics`);
if (!r.ok) {
  const { message } = await r.json();
  console.error('analytics failed:', message); // underlying cause
}
Defensive patterns

Strategy: try-catch

Validate before calling

const convs = await (await fetch('/api/conversations')).json();
const conv = convs.conversations.find(c => c.id === id);
if (conv && !fs.existsSync(conv.filePath)) alert('Conversation file missing on disk');

Try / catch

const r = await fetch(url); if (!r.ok) { const { message } = await r.json(); /* message holds the root cause */ showRetryable(message); }

Prevention

When it happens

Trigger: The conversation id matched, but this.conversationAnalyzer.getParsedConversation(conversation.filePath) throws — missing/unreadable JSONL file, malformed message lines, or a changed Claude Code export format the parser doesn't understand.

Common situations: Conversation file deleted or moved after the index was built; a partially-written or corrupted JSONL file from a crashed session; newer Claude Code message schema breaking the analyzer; permissions issues reading ~/.claude/projects.

Related errors


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