thedotmack/claude-mem · error
Backfill failed: ${error instanceof Error ? error.message :
Error message
Backfill failed: ${error instanceof Error ? error.message : String(error)} What it means
Thrown by ChromaSync.ensureBackfilled when runBackfillPipeline throws after ensureCollectionExists succeeded. It wraps the underlying error (preserving its message) as a plain Error. The original error is logged at CHROMA_SYNC/backfill-failed with the full Error object. The pipeline runs backfill for observations, summaries, and prompts using per-kind watermarks from ChromaSyncState.
Source
Thrown at src/services/sync/ChromaSync.ts:728
});
logger.info('CHROMA_SYNC', 'Bootstrapped watermarks from Chroma', {
project,
watermarks: ChromaSyncState.get(project)
});
}
async ensureBackfilled(project: string, store: SessionStore): Promise<void> {
logger.info('CHROMA_SYNC', 'Starting smart backfill', { project });
await this.ensureCollectionExists();
const watermarks = ChromaSyncState.get(project);
try {
await this.runBackfillPipeline(store, project, watermarks);
} catch (error) {
logger.error('CHROMA_SYNC', 'Backfill failed', { project }, error instanceof Error ? error : new Error(String(error)));
throw new Error(`Backfill failed: ${error instanceof Error ? error.message : String(error)}`);
}
}
private async runBackfillPipeline(
db: SessionStore,
backfillProject: string,
watermarks: ProjectWatermarks
): Promise<void> {
const observationDocs = await this.backfillObservations(db, backfillProject, watermarks.observations);
const summaryDocs = await this.backfillSummaries(db, backfillProject, watermarks.summaries);
const promptDocs = await this.backfillPrompts(db, backfillProject, watermarks.prompts);
logger.info('CHROMA_SYNC', 'Smart backfill complete', {
project: backfillProject,
synced: { observationDocs, summaryDocs, promptDocs },
watermarks: ChromaSyncState.get(backfillProject)
});
}View on GitHub (pinned to d768ba3643)
Solutions
- Read the wrapped error message (the ${error.message}) — it carries the specific stage and underlying cause.
- Check the CHROMA_SYNC error log for the full Error object with stack and project context.
- If the cause is a Chroma connection drop, ensure chroma-mcp is healthy (probeSemanticSearch / isHealthy) then retry ensureBackfilled.
- For huge first-time backfills, run backfill in smaller batches or pre-warm chroma before triggering it.
- Verify ChromaSyncState watermarks are consistent with the DB; a corrupt watermark can cause re-processing or gaps.
Example fix
// before: backfill aborts the whole sync on any sub-stage failure
await chromaSync.ensureBackfilled(project, store);
// after: isolate per-kind backfill so one kind's failure does not abort the others
for (const kind of ['observations','summaries','prompts']) {
try { await chromaSync.ensureBackfilled(project, store); }
catch (e) { log.warn(`backfill kind ${kind} failed, will retry`, e); }
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: ensure chroma is reachable before backfill
if (!(await chromaMcp.isHealthy())) { throw new Error('chroma not healthy; skip backfill'); } Type guard
function isBackfillFailure(e: unknown): boolean {
return e instanceof Error && /^Backfill failed:/i.test(e.message);
} Try / catch
try { await chromaSync.ensureBackfilled(project, store); }
catch (e) {
if (isBackfillFailure(e)) { log.warn('backfill failed, will retry next cycle', e); return; }
throw e;
} Prevention
- Run ensureBackfilled only after chroma-mcp passes a health/probe check.
- For large first-time backfills, chunk by watermark ranges to limit blast radius.
- Keep ChromaSyncState watermarks consistent with the DB to avoid re-processing.
- Log the wrapped inner error so the specific failing stage is identifiable.
When it happens
Trigger: Any of backfillObservations/backfillSummaries/backfillPrompts throws — e.g. a chroma upsert returned isError, a transport error propagated from ChromaMcpManager, or the SessionStore query for rows-past-watermark failed.
Common situations: First-time backfill on a large DB overwhelms chroma or times out; the ChromaMcpManager connection dropped mid-backfill; a malformed row triggered a tool-level error 105; watermarks out of sync with actual DB state.
Related errors
- Chroma mutation queue is full (${this.pendingMutationCalls}/
- chroma-mcp connection in backoff (${Math.ceil((RECONNECT_BAC
- uvx executable not found for chroma-mcp (${uvxSpawnCommand})
- Unable to acquire Chroma writer lock at ${lockPath}: ${error
- Chroma writer lock at ${lockPath} is unreadable; refusing to
AI-assisted analysis of thedotmack/claude-mem@d768ba3643 (2026-08-12).
Data as JSON: /api/errors/7ddbdcd5faf329de.
Report an issue: GitHub.