thedotmack/claude-mem · error · ChromaUnavailableError

CHROMA_UNAVAILABLE

CHROMA_UNAVAILABLE

Error message

Chroma query failed: ${errorObj.message}

What it means

Thrown by SearchOrchestrator.executeWithFallback when the ChromaSearchStrategy.search call rejects. The original error is wrapped in a ChromaUnavailableError (an AppError, HTTP 503, code CHROMA_UNAVAILABLE) preserving the cause message. It signals the semantic-search backend is unreachable or malfunctioning; callers can fall back to SQLite.

Source

Thrown at src/services/worker/search/SearchOrchestrator.ts:68

    options: NormalizedParams
  ): Promise<StrategySearchResult> {
    if (!options.query) {
      logger.debug('SEARCH', 'Orchestrator: Filter-only query, using SQLite', {});
      return await this.sqliteStrategy.search(options);
    }

    if (this.chromaStrategy) {
      logger.debug('SEARCH', 'Orchestrator: Using Chroma semantic search', {});
      try {
        const chromaResult = await this.chromaStrategy.search(options);
        if (options.platformSource && this.isEmptyResult(chromaResult)) {
          logger.debug('SEARCH', 'Orchestrator: platform-scoped Chroma search returned zero matches; falling back to SQLite', {});
          return await this.sqliteStrategy.search(options);
        }
        return chromaResult;
      } catch (error) {
        const errorObj = error instanceof Error ? error : new Error(String(error));
        throw new ChromaUnavailableError(
          `Chroma query failed: ${errorObj.message}`,
          errorObj
        );
      }
    }

    logger.debug('SEARCH', 'Orchestrator: Chroma not configured', {});
    return {
      results: { observations: [], sessions: [], prompts: [] },
      usedChroma: false,
      strategy: 'sqlite'
    };
  }

  private isEmptyResult(result: StrategySearchResult): boolean {
    return result.results.observations.length === 0
      && result.results.sessions.length === 0
      && result.results.prompts.length === 0;

View on GitHub (pinned to d768ba3643)

Solutions

  1. Verify the Chroma server/process is running and reachable (check ~/.claude-mem/chroma).
  2. Ensure uv (Python) is installed so Chroma can start; check sync logs (ChromaSync).
  3. Catch ChromaUnavailableError in the caller and fall back to SQLite search (strategy 'sqlite').
  4. Re-run ChromaSync to populate/re-embed collections if the collection is empty or missing.

Example fix

// before
const result = await orchestrator.search(args);

// after
import { ChromaUnavailableError } from './errors';
try {
  const result = await orchestrator.search(args);
} catch (err) {
  if (err instanceof ChromaUnavailableError) {
    logger.warn('SEARCH', 'Chroma down, falling back to SQLite');
    return sqliteFallback(args);
  }
  throw err;
}
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-flight: only use Chroma if it's healthy
async function isChromaAvailable(chromaSync: ChromaSync | null): Promise<boolean> {
  if (!chromaSync) return false;
  try { await chromaSync.ping(); return true; } catch { return false; }
}

Type guard

import { ChromaUnavailableError } from './errors';
function isChromaUnavailable(e: unknown): e is ChromaUnavailableError {
  return e instanceof ChromaUnavailableError;
}

Try / catch

try {
  return await orchestrator.search(args);
} catch (err) {
  if (err instanceof ChromaUnavailableError) {
    logger.warn('SEARCH', 'Chroma unavailable, using SQLite fallback', { cause: err.message });
    return sqliteStrategy.search(normalizeParams(args));
  }
  throw err;
}

Prevention

When it happens

Trigger: chromaStrategy.search(options) throws — e.g., Chroma server down, collection missing, embedding error, network refusal. Only reached when this.chromaStrategy is non-null (chromaSync configured).

Common situations: Chroma server not running or unreachable; Chroma collection never synced/embedded; uv/Python dependency for Chroma missing; embedding model misconfigured; connection timeout to Chroma.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12). Data as JSON: /api/errors/05a976de76bd225a. Report an issue: GitHub.