thedotmack/claude-mem · error

Chroma query failed - connection lost: ${errorMessage}

Error message

Chroma query failed - connection lost: ${errorMessage}

What it means

Thrown by ChromaSync.queryChroma when the chroma_query_documents call fails and the error message contains a connection-loss signature: 'ECONNREFUSED', 'ENOTFOUND', 'fetch failed', 'subprocess closed', or 'timed out'. collectionCreated is reset to false (so the next ensureCollectionExists re-creates) and the error is rethrown as a plain Error. The code comments note an anti-pattern: ChromaMcpManager re-wraps transport failures as plain Errors, so detection must substring-match the message text instead of reading an error code.

Source

Thrown at src/services/sync/ChromaSync.ts:1012

        n_results: limit,
        ...(whereFilter && { where: whereFilter }),
        include: ['documents', 'metadatas', 'distances']
      });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error);

      const isConnectionError =
        errorMessage.includes('ECONNREFUSED') || // [ANTI-PATTERN IGNORED]: ChromaMcpManager.callTool re-wraps transport failures as plain Errors, so the Node error code only survives in the message text; the full error object is logged below.
        errorMessage.includes('ENOTFOUND') || // [ANTI-PATTERN IGNORED]: same MCP transport re-wrapping as above; no structured code field is available on the re-wrapped error.
        errorMessage.includes('fetch failed') || 
        errorMessage.includes('subprocess closed') || 
        errorMessage.includes('timed out'); 

      if (isConnectionError) {
        this.collectionCreated = false;
        logger.error('CHROMA_SYNC', 'Connection lost during query',
          { project: this.project, query }, error as Error);
        throw new Error(`Chroma query failed - connection lost: ${errorMessage}`);
      }

      logger.error('CHROMA_SYNC', 'Query failed', { project: this.project, query }, error as Error);
      throw error;
    }

    return this.deduplicateQueryResults(results);
  }

  private deduplicateQueryResults(results: any): { ids: number[]; distances: number[]; metadatas: any[] } {
    const ids: number[] = [];
    const seen = new Set<string>();
    const docIds = results?.ids?.[0] || [];
    const rawMetadatas = results?.metadatas?.[0] || [];
    const rawDistances = results?.distances?.[0] || [];

    const metadatas: any[] = [];
    const distances: number[] = [];

View on GitHub (pinned to d768ba3643)

Solutions

  1. Confirm chroma-mcp is alive (isHealthy / probeSemanticSearch) and let ensureConnected/prewarm restart it.
  2. Reduce query cost (smaller n_results / limit, tighter whereFilter) to avoid the 'timed out' path.
  3. Because collectionCreated is reset, expect a re-create on the next call — ensure the data dir is writable.
  4. Investigate memory pressure / OOM kills if 'subprocess closed' recurs.
  5. Retry the query after a short backoff; this error is inherently transient.

Example fix

// before: query surfaces a fatal-looking connection error
const r = await chromaSync.queryChroma(q, 10);
// after: treat the connection-lost signature as transient
try { return await chromaSync.queryChroma(q, 10); }
catch (e) { if (/connection lost/.test(e.message)) { await sleep(500); return retry(); } throw e; }
Defensive patterns

Strategy: retry

Type guard

function isQueryConnectionLost(e: unknown): boolean {
  return e instanceof Error && /Chroma query failed - connection lost/i.test(e.message);
}

Try / catch

try { return await chromaSync.queryChroma(q, limit, whereFilter); }
catch (e) {
  if (isQueryConnectionLost(e)) { await sleep(500); return await chromaSync.queryChroma(q, limit, whereFilter); }
  throw e;
}

Prevention

When it happens

Trigger: chroma_query_documents threw; the thrown message includes one of the network/subprocess signatures — most commonly because chroma-mcp transport died (error 104), the subprocess was closed, or a fetch to the embedded chroma timed out.

Common situations: Chroma subprocess crashed under load; the OS refused a connection (port gone because subprocess exited); a slow query exceeded the timeout; the machine briefly lost loopback connectivity; chroma-mcp was OOM-killed during a large query.

Related errors


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