thedotmack/claude-mem · error · ChromaUnavailableError
chroma-mcp prewarm failed
Error message
chroma-mcp prewarm failed: ${errorMessage} What it means
Thrown by the ChromaMcpManager prewarm path when spawning/waiting for the chroma-mcp child (via uvx) fails or times out. The manager kills the child, records vector search as unavailable via recordUvxVectorSearchUnavailable, and throws ChromaUnavailableError with the underlying error message. Prewarming is the eager startup of the MCP server so later vector searches do not pay cold-start cost.
Solutions
- Run `uvx chroma-mcp --help` manually to verify uvx and the chroma-mcp package work outside the plugin; install/upgrade with `uv` if missing
- Increase the prewarm timeout or pre-warm once manually so the uvx package cache is populated, avoiding first-run download timeouts
- Check network/proxy settings if uvx is downloading the package (set HTTPS_PROXY, or pre-install chroma-mcp into the uv environment)
- Read the full error detail: the wrapped `error` in ChromaUnavailableError carries the child's stderr - fix the root cause it reports (e.g., invalid --data-dir, port conflicts)
- If the chroma data dir schema is from an older Chroma version, move/delete it so chroma-mcp can initialize a compatible one
Defensive patterns
Strategy: fallback
Validate before calling
import { execSync } from 'child_process';
function uvxAvailable(): boolean {
try { execSync('uvx --version', { stdio: 'ignore' }); return true; } catch { return false; }
}
if (!uvxAvailable()) {
// install uv first: curl -LsSf https://astral.sh/uv/install.sh | sh
} Type guard
function isChromaUnavailableError(e: unknown): e is ChromaUnavailableError {
return e instanceof ChromaUnavailableError;
} Try / catch
try {
await manager.connect();
} catch (e) {
if (isChromaUnavailableError(e) && e.message.startsWith('chroma-mcp prewarm failed')) {
// degrade: disable vector search features, keep the rest of the plugin working
disableVectorSearchFeatures();
logger.warn('Chroma prewarm failed; continuing without vector search', e.cause);
} else throw e;
} Prevention
- Install and keep uv/uvx on PATH and updated so chroma-mcp can spawn
- Warm the uvx cache once manually (`uvx chroma-mcp --help`) so first plugin start does not race a package download
- Ensure network/proxy allows reaching the package index where chroma-mcp is fetched from
- Keep the chroma-mcp package version compatible with the data dir schema; migrate or reset the data dir after major Chroma upgrades
- Log/inspect the wrapped cause error - it contains the child stderr pointing at the real failure
When it happens
Trigger: chroma-mcp child exits with non-zero status, the prewarm timeout elapses before the server signals readiness, or spawning the uvx/chroma-mcp command fails (command missing, uv environment broken); errorMessage is the failure text embedded in this message.
Common situations: uv/uvx not installed or not on PATH; first-run uvx download of chroma-mcp package too slow and hits the prewarm timeout; Python/uv environment broken (uv python install failed); corporate proxy blocking package download; chroma-mcp version incompatible with the data dir schema.
Related errors
- chroma-mcp uvx prewarm failed
- Chroma query failed - connection lost
- Connection failed, killing subprocess tree to prevent zombie
- failed to kill in-flight chroma-mcp prewarm tree…
- uvx executable not found for chroma-mcp
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/2bde5cffa5735723.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/sync/ChromaMcpManager.ts:788
if (pid) {
try {
// Token from spawn time: by here the prewarm may already have exited
// (that is often WHY we are in this branch), so self-capture would
// read a replacement rather than the child we spawned.
await killProcessTree(pid, { expectedStartToken: prewarmTracked?.startToken ?? null });
} catch (killError) {
logger.debug('CHROMA_MCP', 'prewarm process tree kill finished (best-effort)', {
pid,
error: killError instanceof Error ? killError.message : String(killError)
});
}
} else {
try { child.kill('SIGKILL'); } catch { /* already dead */ }
}
const unavailableMessage = `chroma-mcp prewarm failed: ${errorMessage}`;
recordUvxVectorSearchUnavailable(unavailableMessage);
throw new ChromaUnavailableError(unavailableMessage, error instanceof Error ? error : undefined);
} finally {
if (timeoutId) {
clearTimeout(timeoutId);
}
if (this.activePrewarmChild === child) {
this.activePrewarmChild = null;
this.activePrewarmTracked = null;
}
}
}
async callTool(toolName: string, toolArguments: Record<string, unknown>): Promise<unknown> {
if (!this.serializeMutations || !ChromaMcpManager.isMutationTool(toolName)) {
return this.callToolUnqueued(toolName, toolArguments);
}
if (!this.acceptingLocalMutations) {
throw new ChromaUnavailableError('Local Chroma mutations are unavailable after shutdown begins');
}View on GitHub (pinned to d8bc9755e7)