thedotmack/claude-mem · warning

Service initializing

Service initializing

Error message

Database is still initializing, please retry

What it means

HTTP 503 returned by a global middleware on the worker's /api and /v1 route trees when a request arrives before the database initialization completes (initializationCompleteFlag is false). It is a startup gate, not a fault: only /health, /readiness, /version, /chroma/status and /settings/dependency-health are exempt and always served. The body carries error 'Service initializing' with an explicit instruction to retry.

Source

Thrown at src/services/worker-service.ts:347

    this.server.app.use(['/api', '/v1'], async (req, res, next) => {
      if (
        req.path === '/chroma/status' ||
        req.path === '/health' ||
        req.path === '/readiness' ||
        req.path === '/version' ||
        req.path === '/settings/dependency-health'
      ) {
        next();
        return;
      }

      if (this.initializationCompleteFlag) {
        next();
        return;
      }

      logger.debug('WORKER', `Request to ${req.method} ${req.path} rejected — DB not initialized`);
      res.status(503).json({
        error: 'Service initializing',
        message: 'Database is still initializing, please retry'
      });
      return;
    });

    this.server.registerRoutes(new ViewerRoutes(this.sseBroadcaster, this.dbManager, this.sessionManager));
    const sessionRoutes = new SessionRoutes(this.sessionManager, this.dbManager, this.sdkAgent, this.geminiAgent, this.openRouterAgent, this.sessionEventBroadcaster, this, this.completionHandler);
    this.server.registerRoutes(sessionRoutes);
    attachIngestGeneratorStarter((sessionDbId, source) =>
      sessionRoutes.ensureGeneratorRunning(sessionDbId, source),
    );
    this.server.registerRoutes(new DataRoutes(this.paginationHelper, this.dbManager, this.sessionManager, this.sseBroadcaster, this, this.startTime));
    this.server.registerRoutes(new SettingsRoutes(this.settingsManager));
    this.server.registerRoutes(new LogsRoutes());
    this.server.registerRoutes(new MemoryRoutes(this.dbManager, 'claude-mem'));
    this.server.registerRoutes(new ServerV1Routes({
      getDatabase: () => this.dbManager.getConnection(),

View on GitHub (pinned to e2d1df569a)

Solutions

  1. Retry the same request with exponential backoff (the condition is transient and self-clearing once init finishes)
  2. Poll the exempt GET /api/health or /api/readiness endpoint until it reports ready before issuing other calls
  3. If 503 persists past a minute, check worker logs for a stuck initialization (locked SQLite file, missing uv/Chroma deps)

Example fix

// before
const res = await fetch('http://127.0.0.1:37777/api/sessions');
const data = await res.json(); // 503 during boot

// after
async function waitReady(base: string) {
  for (let i = 0; i < 30; i++) {
    const h = await fetch(`${base}/api/health`);
    if (h.ok) return;
    await new Promise(r => setTimeout(r, 1000));
  }
  throw new Error('worker not ready after 30s');
}
await waitReady(base);
const res = await fetch(`${base}/api/sessions`);
Defensive patterns

Strategy: retry

Validate before calling

async function workerReady(base: string): Promise<boolean> {
  try {
    const r = await fetch(`${base}/api/health`); // exempt from the init gate
    return r.ok;
  } catch { return false; }
}

Type guard

function isInitializingResponse(body: unknown, status: number): boolean {
  return status === 503 &&
    typeof body === 'object' && body !== null &&
    (body as { error?: string }).error === 'Service initializing';
}

Try / catch

for (let attempt = 0; attempt < 10; attempt++) {
  const res = await callApi();
  if (res.status !== 503) return handle(res);
  await sleep(500 * 2 ** attempt);
}
throw new Error('worker still initializing after retries');

Prevention

When it happens

Trigger: Any API call to /api/* or /v1/* issued between worker listen() and the end of DB initialization (session store open, migrations, Chroma boot). Typically a client fires requests immediately after spawning the worker instead of waiting for readiness.

Common situations: Scripts that start `claude-mem worker` and instantly call search/session endpoints; restarts on large databases where init takes seconds-to-minutes; health-checkers probing a non-exempt path; CI that treats 503 as fatal instead of retrying.

Related errors


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