{"record":{"id":"05379f592c572818","repo":"thedotmack/claude-mem","slug":"chroma-query-failed-connection-lost-errormess","errorCode":null,"errorMessage":"Chroma query failed - connection lost: ${errorMessage}","messagePattern":"Chroma query failed - connection lost: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/sync/ChromaSync.ts","lineNumber":1106,"sourceCode":"        n_results: limit,\n        ...(whereFilter && { where: whereFilter }),\n        include: ['documents', 'metadatas', 'distances']\n      });\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n\n      const isConnectionError =\n        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.\n        errorMessage.includes('ENOTFOUND') || // [ANTI-PATTERN IGNORED]: same MCP transport re-wrapping as above; no structured code field is available on the re-wrapped error.\n        errorMessage.includes('fetch failed') || \n        errorMessage.includes('subprocess closed') || \n        errorMessage.includes('timed out'); \n\n      if (isConnectionError) {\n        this.collectionCreated = false;\n        logger.error('CHROMA_SYNC', 'Connection lost during query',\n          { project: this.project, query }, error as Error);\n        throw new Error(`Chroma query failed - connection lost: ${errorMessage}`);\n      }\n\n      logger.error('CHROMA_SYNC', 'Query failed', { project: this.project, query }, error as Error);\n      throw error;\n    }\n\n    return this.deduplicateQueryResults(results);\n  }\n\n  private deduplicateQueryResults(results: any): { ids: number[]; distances: number[]; metadatas: any[] } {\n    const ids: number[] = [];\n    const seen = new Set<string>();\n    const docIds = results?.ids?.[0] || [];\n    const rawMetadatas = results?.metadatas?.[0] || [];\n    const rawDistances = results?.distances?.[0] || [];\n\n    const metadatas: any[] = [];\n    const distances: number[] = [];","sourceCodeStart":1088,"sourceCodeEnd":1124,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/sync/ChromaSync.ts#L1088-L1124","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst results = await chromaSync.query(project, queryText);\n// after\nlet results;\ntry {\n  results = await chromaSync.query(project, queryText);\n} catch (e) {\n  if (String(e.message).includes('connection lost')) {\n    await sleep(1000);\n    results = await chromaSync.query(project, queryText);\n  } else throw e;\n}","handlingStrategy":"retry","validationCode":"// health-check Chroma before heavy query loops\nconst healthy = await fetch(`${chromaBaseUrl}/api/v1/heartbeat`, { signal: AbortSignal.timeout(3000) }).then(r => r.ok).catch(() => false);\nif (!healthy) await reconnectChroma();","typeGuard":null,"tryCatchPattern":"try {\n  results = await chromaSync.query(project, q);\n} catch (e) {\n  if (/Chroma query failed - connection lost/.test(e.message)) {\n    await sleep(1000); results = await chromaSync.query(project, q); // collection is re-created\n  } else throw e;\n}","preventionTips":["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"],"tags":["chroma","connection-lost","timeout","query"],"backgroundTag":"connection-lost","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}