{"record":{"id":"25f5d6c205cf4d16","repo":"thedotmack/claude-mem","slug":"failed-to-kill-in-flight-chroma-mcp-prewarm-tree","errorCode":null,"errorMessage":"failed to kill in-flight chroma-mcp prewarm tree (best-effort)","messagePattern":"failed to kill in-flight chroma-mcp prewarm tree \\(best-effort\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/sync/ChromaMcpManager.ts","lineNumber":957,"sourceCode":"    this.transport = null;\n    this.connected = false;\n  }\n\n  private async disposeActivePrewarm(): Promise<void> {\n    const prewarmChild = this.activePrewarmChild;\n    if (!prewarmChild) {\n      return;\n    }\n    if (this.activePrewarmChild === prewarmChild) {\n      this.activePrewarmChild = null;\n    }\n\n    const pid = prewarmChild.pid;\n    if (pid) {\n      try {\n        await ChromaMcpManager.killProcessTree(pid);\n      } catch (error) {\n        logger.warn('CHROMA_MCP', 'failed to kill in-flight chroma-mcp prewarm tree (best-effort)', {\n          pid,\n          error: error instanceof Error ? error.message : String(error)\n        });\n      }\n    }\n\n    try {\n      prewarmChild.kill('SIGKILL');\n    } catch {\n      // Already dead.\n    }\n\n    await ChromaMcpManager.waitForChildClose(prewarmChild, CHROMA_PREWARM_REAP_TIMEOUT_MS);\n  }\n\n  private static async waitForChildClose(child: ChildProcess, timeoutMs: number): Promise<void> {\n    if (child.exitCode !== null || child.signalCode !== null) {\n      return;","sourceCodeStart":939,"sourceCodeEnd":975,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/services/sync/ChromaMcpManager.ts#L939-L975","documentation":"While cleaning up an in-flight uvx prewarm child, killProcessTree(pid) failed. A direct prewarmChild.kill('SIGKILL') is still attempted right after, so the child usually dies anyway; the residual risk is an orphaned uvx/python process from the prewarm.","triggerScenarios":"The prewarm child exited between pid capture and the tree-kill (ESRCH race), permission denied on the process, or an external reaper claiming it first.","commonSituations":"Shutdown racing prewarm startup; external process supervisors; PID-namespace restrictions in containers.","solutions":["Scan for stragglers with pgrep -af 'uvx|chroma-mcp' and kill them","Normally self-healing via the SIGKILL fallback — act only if orphans persist","Upgrade if this recurs, since newer builds add extra kill fallbacks"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check for orphaned uvx/chroma-mcp processes after forced shutdowns","Let shutdown complete rather than SIGKILLing the parent worker","The SIGKILL fallback in this path usually reaps the child; only intervene if orphans persist"],"tags":["chroma","process-cleanup","prewarm","shutdown"],"backgroundTag":"process-kill-failed","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}