thedotmack/claude-mem · error · Error
Chroma query failed - connection lost
Error message
Chroma query failed - connection lost: ${errorMessage} What it means
ChromaSync.query detects connection-class failures (the error message includes connection-loss indicators such as timeouts) while querying Chroma. It resets collectionCreated so the next call re-creates the collection, logs the failure, and throws a new Error 'Chroma query failed - connection lost: <msg>'. This signals that the Chroma connection must be re-established, not just retried blindly.
Solutions
- Retry the query after a short delay; collectionCreated was reset so the collection/connection is re-established automatically.
- Verify the Chroma server is running and reachable at the configured host/port.
- Add keep-alive or lower idle timeouts on proxies between the app and Chroma.
- Catch this error and trigger a re-probe/reconnect before resuming sync.
- Increase the query timeout if queries legitimately take longer than the server timeout.
Example fix
// before
const results = await chromaSync.query(project, queryText);
// after
let results;
try {
results = await chromaSync.query(project, queryText);
} catch (e) {
if (String(e.message).includes('connection lost')) {
await sleep(1000);
results = await chromaSync.query(project, queryText);
} else throw e;
} Defensive patterns
Strategy: retry
Validate before calling
// health-check Chroma before heavy query loops
const healthy = await fetch(`${chromaBaseUrl}/api/v1/heartbeat`, { signal: AbortSignal.timeout(3000) }).then(r => r.ok).catch(() => false);
if (!healthy) await reconnectChroma(); Try / catch
try {
results = await chromaSync.query(project, q);
} catch (e) {
if (/Chroma query failed - connection lost/.test(e.message)) {
await sleep(1000); results = await chromaSync.query(project, q); // collection is re-created
} else throw e;
} Prevention
- Retry with backoff: connection errors are transient after collectionCreated reset
- Keep idle keep-alive settings on any proxy between app and Chroma
- Set realistic query timeouts so long queries aren't mistaken for connection loss
- Probe Chroma heartbeat periodically to detect drops before queries fail
When it happens
Trigger: A query() call against Chroma where the underlying error is a connection drop, socket error, or timeout (errorMessage includes the connection-error markers checked in isConnectionError).
Common situations: Chroma server restarted or OOM-killed mid-session, idle connection reaped by a proxy/load balancer, network partition between app and Chroma, or query exceeding server timeout.
Related errors
- chroma-mcp prewarm failed
- Backfill failed
- Chroma data dir is already owned by PID ; refusing to start…
- chroma-mcp call cancelled during shutdown
- chroma-mcp connection cancelled during shutdown
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/05379f592c572818.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/sync/ChromaSync.ts:1106
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 d8bc9755e7)