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
- Confirm chroma-mcp is alive (isHealthy / probeSemanticSearch) and let ensureConnected/prewarm restart it.
- Reduce query cost (smaller n_results / limit, tighter whereFilter) to avoid the 'timed out' path.
- Because collectionCreated is reset, expect a re-create on the next call — ensure the data dir is writable.
- Investigate memory pressure / OOM kills if 'subprocess closed' recurs.
- 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
- Reduce query cost (smaller limit, tighter whereFilter) to avoid the 'timed out' signature.
- Keep chroma-mcp healthy and memory-safe to avoid 'subprocess closed'.
- Expect collectionCreated to be reset after this error; ensure the data dir is writable for re-create.
- Treat this error as transient and retry with backoff.
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
- chroma-mcp connection in backoff (${Math.ceil((RECONNECT_BAC
- uvx executable not found for chroma-mcp (${uvxSpawnCommand})
- Unable to acquire Chroma writer lock at ${lockPath}: ${error
- Chroma writer lock at ${lockPath} is unreadable; refusing to
- Unable to remove stale Chroma writer lock at ${lockPath}: ${
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/05379f592c572818.
Report an issue: GitHub.