thedotmack/claude-mem · warning

Service initializing

Error message

Service initializing

What it means

HTTP 503 from the viewer's SSE endpoint. It probes dbManager.getSessionStore() as an initialization canary: during worker startup that call throws, the handler logs 'SSE stream requested before DB initialization' at WARN and refuses to open the event stream. Unlike the global /api gate (error 240), this guard is local to the viewer stream connection.

Source

Thrown at src/services/worker/http/routes/ViewerRoutes.ts:81

    });
  });

  private handleViewerUI = this.wrapHandler((req: Request, res: Response): void => {
    if (!viewerHtmlBytes) {
      throw new Error('Viewer UI not found at any expected location');
    }
    res.setHeader('Content-Type', 'text/html; charset=utf-8');
    res.send(viewerHtmlBytes);
  });

  private handleSSEStream = this.wrapHandler((req: Request, res: Response): void => {
    try {
      this.dbManager.getSessionStore();
    } catch (initError: unknown) {
      if (initError instanceof Error) {
        logger.warn('HTTP', 'SSE stream requested before DB initialization', {}, initError);
      }
      res.status(503).json({ error: 'Service initializing' });
      return;
    }

    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    this.sseBroadcaster.addClient(res);

    const projectCatalog = this.dbManager.getSessionStore().getProjectCatalog();
    this.sseBroadcaster.broadcast({
      type: 'initial_load',
      projects: projectCatalog.projects,
      sources: projectCatalog.sources,
      projectsBySource: projectCatalog.projectsBySource,
      timestamp: Date.now()
    });

View on GitHub (pinned to e2d1df569a)

Solutions

  1. Let EventSource reconnect (it will succeed once init completes); configure reconnect with a small backoff
  2. Gate the viewer page on /api/health returning ok before mounting the SSE client
  3. If 503 persists, check worker logs for a session-store initialization failure (locked or missing SQLite database)

Example fix

// before
const es = new EventSource(`${base}/sse`); // 503 during boot, no retry logic

// after
async function connectWhenReady() {
  while (!(await fetch(`${base}/api/health`).then(r => r.ok).catch(() => false)))
    await new Promise(r => setTimeout(r, 500));
  return new EventSource(`${base}/sse`);
}
Defensive patterns

Strategy: retry

Validate before calling

while (!(await fetch(`${base}/api/health`).then(r => r.ok).catch(() => false)))
  await new Promise(r => setTimeout(r, 500));
const es = new EventSource(`${base}/sse`); // connect only after readiness

Type guard

function isInitializing(res: Response): boolean {
  return res.status === 503; // SSE endpoint's only 503 is the pre-init canary
}

Try / catch

// EventSource reconnects automatically; just don't crash the page on the first 503:
es.onerror = () => { /* keep the listener; it will succeed after init */ };

Prevention

When it happens

Trigger: A browser or EventSource client opens /sse (or the viewer page auto-connects) in the window between HTTP listen and DB initialization completing; aggressive reconnect logic hammering the endpoint during a slow boot.

Common situations: Viewer page opened immediately after worker start; EventSource auto-reconnect with zero backoff creating 503 bursts; dashboards that load on machine boot before the worker service finishes initializing.

Related errors


AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20). Data as JSON: /api/errors/8538a8b9afd027fe. Report an issue: GitHub.