{"record":{"id":"62609171e6648bce","repo":"thedotmack/claude-mem","slug":"connection-failed-killing-subprocess-tree-to-prev","errorCode":null,"errorMessage":"Connection failed, killing subprocess tree to prevent zombie","messagePattern":"Connection failed, killing subprocess tree to prevent zombie","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/sync/ChromaMcpManager.ts","lineNumber":284,"sourceCode":"    });\n\n    try {\n      await Promise.race([mcpConnectionPromise, timeoutPromise]);\n      this.assertConnectionNotCancelled(connectionGeneration);\n    } catch (connectionError) {\n      clearTimeout(timeoutId!);\n      if (\n        connectionError instanceof ChromaMcpConnectionCancelledError ||\n        this.connectionGeneration !== connectionGeneration\n      ) {\n        logger.debug('CHROMA_MCP', 'MCP connection cancelled during shutdown');\n        await this.disposeCurrentSubprocess();\n        throw connectionError instanceof ChromaMcpConnectionCancelledError\n          ? connectionError\n          : new ChromaMcpConnectionCancelledError();\n      }\n      const stderrTail = transportStderrTail();\n      logger.warn('CHROMA_MCP', 'Connection failed, killing subprocess tree to prevent zombie', {\n        error: connectionError instanceof Error ? connectionError.message : String(connectionError),\n        ...(stderrTail ? { stderrTail } : {})\n      });\n      // Tree-kill (not just transport.close) so failed-connect descendants\n      // can't survive on Linux (#2313).\n      await this.disposeCurrentSubprocess();\n      throw connectionError;\n    }\n    clearTimeout(timeoutId!);\n\n    this.connected = true;\n    this.registerManagedProcess();\n    clearDependencyStatus('chroma');\n\n    logger.info('CHROMA_MCP', 'Connected to chroma-mcp successfully');\n\n    const currentTransport = this.transport;\n    // Captured HERE, while the child is alive and attached — not in the","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/8bc631a71a487424b866756e43a6efa4574cc66b/src/services/sync/ChromaMcpManager.ts#L266-L302","documentation":"The MCP client could not establish a connection to the chroma-mcp subprocess (spawn failure, early exit, or handshake timeout). ChromaMcpManager tree-kills the subprocess so uv/python descendants cannot survive on Linux (#2313), then rethrows the original connection error. Vector search is unavailable until the next connect attempt.","triggerScenarios":"connect() spawning uvx chroma-mcp when uv/uvx is missing from PATH (ENOENT); first-run package download exceeding the connect timeout; an unsupported Python version; the process exiting before the MCP handshake; stderr captured in stderrTail showing import or dependency errors.","commonSituations":"uv not installed or absent from the service PATH (launchd, systemd, CI runners strip PATH); offline or proxied networks blocking PyPI; a stale uv cache holding a corrupted chroma-mcp download.","solutions":["Read the logged error and stderrTail fields — they distinguish spawn failure from crash from timeout","Run the logged command manually (e.g. uvx chroma-mcp) once to warm the cache and surface the real error","Install uv and make sure it is on the PATH of the user running the worker","Raise the connection timeout if first-run downloads are slow on your network","Clear a corrupt cache with: uv cache clean"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nconst execFileP = promisify(execFile);\n\nasync function uvxAvailable(): Promise<boolean> {\n  try {\n    await execFileP('uvx', ['--version']);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n// preflight before first Chroma use\nif (!(await uvxAvailable())) {\n  // degrade to non-vector features instead of attempting connect()\n}","typeGuard":null,"tryCatchPattern":"try {\n  await manager.connect();\n} catch (err) {\n  // run degraded (FTS/LIKE search only); schedule reconnect with backoff;\n  // the manager already tree-killed the failed subprocess\n  enterDegradedMode();\n  scheduleReconnect(30_000);\n}","preventionTips":["Install uv and keep it on the PATH of the service user (systemd/launchd/CI inherit minimal PATHs)","Run uvx chroma-mcp --help once at install time to pre-download the package","Allow PyPI egress so first-resolution does not hit the connect timeout"],"tags":["chroma","mcp","subprocess","uvx","connect-failure"],"backgroundTag":"mcp-subprocess-connect-failed","analyzedSha":"8bc631a71a487424b866756e43a6efa4574cc66b","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}