Skip to content

Worker crashes on runtime Chroma sync timeouts (unhandled promise rejections) #427

Description

@cjpeterein

Environment

  • claude-mem version: 8.0.4
  • OS: Linux ARM64 (6.12.57+deb13-arm64)
  • Bun: 1.3.5
  • Python: 3.13
  • uv: 0.9.18

Problem

The worker crashes during runtime when Chroma MCP sync operations timeout. Unlike the startup crash fixed in #425, this occurs when syncObservation() and syncSummary() are called after observations are saved to SQLite.

The promises lack .catch() handlers, causing unhandled rejections that crash the entire worker process.

Error Details

Worker logs show:

[2025-12-23 22:56:04.702] [ERROR] [CHROMA_SYNC] Failed to add documents {collection=cm__claude-mem, count=5} MCP error -32001: Request timed out

error: Document add failed: MCP error -32001: Request timed out
      at addDocuments (/home/cjp/.claude/plugins/marketplaces/thedotmack/plugin/scripts/worker-service.cjs:722:4498)
      at async syncObservation (/home/cjp/.claude/plugins/marketplaces/thedotmack/plugin/scripts/worker-service.cjs:722:5116)

Bun v1.3.5 (Linux arm64)

Hook error visible to user:

PostToolUse:Read says: Plugin hook "node "/home/cjp/.claude/plugins/cache/thedotmack/claude-mem/8.0.4/scripts/save-hook.js""
failed to start: The operation was aborted.

Root Cause

In src/services/worker/SDKAgent.ts, the Chroma sync calls use .then() without .catch():

// Line ~XXX in SDKAgent.ts
this.dbManager.getChromaSync().syncObservation(
  obsId,
  session.claudeSessionId,
  session.project,
  obs,
  session.lastPromptNumber,
  createdAtEpoch,
  discoveryTokens
).then(() => {
  const chromaDuration = Date.now() - chromaStart;
  logger.debug('CHROMA', 'Observation synced', {
    obsId,
    duration: `${chromaDuration}ms`,
    type: obsType,
    title: obsTitle
  });
});
// No .catch() handler - crashes worker on timeout/error

Same issue exists for syncSummary() calls.

Impact

  • Current behavior: Worker crashes, auto-restarts, but PostToolUse hooks fail
  • Data integrity: ✅ SQLite observations are saved before crash (no data loss)
  • Vector search: ❌ Chroma sync incomplete, semantic search unreliable
  • User experience: ❌ Error messages visible in hook output

Suggested Fix

Add .catch() handlers to gracefully degrade Chroma functionality:

this.dbManager.getChromaSync().syncObservation(
  obsId,
  session.claudeSessionId,
  session.project,
  obs,
  session.lastPromptNumber,
  createdAtEpoch,
  discoveryTokens
).then(() => {
  const chromaDuration = Date.now() - chromaStart;
  logger.debug('CHROMA', 'Observation synced', {
    obsId,
    duration: `${chromaDuration}ms`,
    type: obsType,
    title: obsTitle
  });
}).catch((error) => {
  logger.warn('CHROMA', 'Observation sync failed, continuing without vector search', {
    obsId,
    type: obsType,
    title: obsTitle
  }, error);
});

Apply same pattern to syncSummary() call.

Why This Matters

Similar to #425, this follows the "fail-fast with no fallbacks" design that's appropriate for critical features but inappropriate for optional features like vector search. Core functionality (SQLite storage, memory injection, search via SQLite) should continue working even when Chroma is unavailable.

Workaround

The worker auto-restarts after crashes, so the system remains functional. However:

  • Hook failures are visible to users
  • Logs are noisy with crash reports
  • Chroma sync remains incomplete

Notes

Metadata

Metadata

Labels

bugConfirmed bug

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions