{"record":{"id":"8d4be38885abff69","repo":"thedotmack/claude-mem","slug":"observation-watermark-bump-skipped-partial-write","errorCode":null,"errorMessage":"Observation watermark bump skipped — partial write","messagePattern":"Observation watermark bump skipped — partial write","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/sync/ChromaSync.ts","lineNumber":476,"sourceCode":"\n    const documents = this.formatObservationDocs(stored);\n\n    logger.info('CHROMA_SYNC', 'Syncing observation', {\n      observationId,\n      documentCount: documents.length,\n      project\n    });\n\n    // Only advance the watermark on a confirmed full write. addDocuments() now\n    // returns a written count and tolerates per-batch failures, so a transient\n    // Chroma error must NOT mark this observation as synced — otherwise the\n    // backfill pass on next boot will skip past it (CodeRabbit review on PR\n    // #2282).\n    const written = await this.addDocuments(documents);\n    if (written === documents.length) {\n      ChromaSyncState.bump(project, 'observations', observationId);\n    } else {\n      logger.warn('CHROMA_SYNC', 'Observation watermark bump skipped — partial write', {\n        observationId,\n        project,\n        requested: documents.length,\n        written\n      });\n    }\n  }\n\n  async syncSummary(\n    summaryId: number,\n    memorySessionId: string,\n    project: string,\n    summary: ParsedSummary,\n    promptNumber: number,\n    createdAtEpoch: number,\n    platformSource?: string\n  ): Promise<void> {\n    const stored: StoredSummary = {","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/e2d1df569a8f04075d40e92461128ece7cf04c82/src/services/sync/ChromaSync.ts#L458-L494","documentation":"syncObservation advances the observations watermark in ChromaSyncState only when addDocuments reports written === requested. A partial write (per-batch failures are tolerated inside addDocuments) skips the bump and logs this warning, so the next boot's backfill retries the observation instead of silently skipping it (CodeRabbit review on PR #2282).","triggerScenarios":"Chroma accepts some batches but fails others (transient error, timeout) during an observation sync, returning written < documents.length.","commonSituations":"Chroma briefly overloaded or restarting, embedder rate limits, or a network hiccup mid-write.","solutions":["Wait for the automatic backfill on next boot — the data is not lost.","Check Chroma connectivity/health and fix the transient cause.","Confirm later that observation counts converge; do not hand-edit the watermark."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"async function chromaHealthy(baseUrl: string): Promise<boolean> {\n  try {\n    const res = await fetch(`${baseUrl}/api/v2/heartbeat`, { signal: AbortSignal.timeout(2000) });\n    return res.ok;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat watermark bumps as write confirmations, not attempt confirmations.","Keep Chroma reachable during sync windows to avoid backfill debt."],"tags":["chroma","sync","watermark","partial-write","idempotency"],"backgroundTag":"partial-write-retry","analyzedSha":"e2d1df569a8f04075d40e92461128ece7cf04c82","analyzedAt":"2026-08-20T23:58:13.836Z","contentChangedAt":"2026-08-20T23:58:13.836Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}