{"record":{"id":"74b1d3ee0fbae35e","repo":"thedotmack/claude-mem","slug":"unreadable-chroma-sync-state-json-treating-as-empty","errorCode":null,"errorMessage":"Unreadable chroma-sync-state.json, treating as empty","messagePattern":"Unreadable chroma-sync-state\\.json, treating as empty","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/sync/ChromaSyncState.ts","lineNumber":72,"sourceCode":"  }\n\n  return normalized;\n}\n\nfunction load(): Record<string, ProjectWatermarks> {\n  if (cache) return cache;\n  const path = statePath();\n  if (!existsSync(path)) {\n    cache = {};\n    return cache;\n  }\n  let parsed: Record<string, Partial<ProjectWatermarks>>;\n  try {\n    parsed = readJsonFileWithBom<Record<string, Partial<ProjectWatermarks>>>(path);\n  } catch (error) {\n    // A truncated or corrupt state file must not abort the sync pipeline. Treat\n    // it as empty and rebuild from the SQLite watermarks on the next backfill.\n    logger.warn('CHROMA_SYNC', 'Unreadable chroma-sync-state.json, treating as empty', {\n      path\n    }, error instanceof Error ? error : new Error(String(error)));\n    cache = {};\n    return cache;\n  }\n  const normalized: Record<string, ProjectWatermarks> = {};\n  for (const [project, marks] of Object.entries(parsed)) {\n    normalized[project] = normalizeProjectWatermarks(marks);\n  }\n  cache = normalized;\n  return cache;\n}\n\nfunction persist(): void {\n  if (!cache) return;\n  writeJsonFileAtomic(statePath(), cache);\n}\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/sync/ChromaSyncState.ts#L54-L90","documentation":"load() reads chroma-sync-state.json; if parsing fails (truncated/corrupt file, BOM/encoding issues not tolerated, invalid JSON), the state is treated as empty and the warning logged so the sync pipeline continues and rebuilds watermarks via backfill.","triggerScenarios":"The state file is truncated by a crash mid-write, contains invalid JSON from manual editing, or readJsonFileWithBom throws for any IO/parse reason.","commonSituations":"Machine crash/power loss while the file was being written, disk-full during write, manual edits with syntax errors, sync tools corrupting the file.","solutions":["Delete or rename the corrupt ~/.claude-mem/chroma-sync-state.json; it will be recreated empty.","Let the next backfill rebuild watermarks from SQLite (automatic).","Restore the file from backup if you need prior watermark state to avoid a full re-sync.","Check disk space and that no crash occurs mid-write (atomic write with temp file + rename)."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"import { readFileSync } from 'fs';\nfunction stateFileIsParsable(path: string): boolean {\n  try { JSON.parse(readFileSync(path, 'utf8')); return true; } catch { return false; }\n}","typeGuard":"const isWatermarkState = (v: unknown): v is Record<string, Partial<ProjectWatermarks>> =>\n  typeof v === 'object' && v !== null && !Array.isArray(v);","tryCatchPattern":"try { parsed = readJsonFileWithBom(path); }\ncatch (e) {\n  logger.warn('state file unreadable; treating as empty', { path }, e);\n  cache = {};\n}","preventionTips":["Write state atomically (temp file + rename)","Restore state files from backup after crashes instead of deleting silently","Validate state JSON after manual edits","Monitor disk space on the state directory"],"tags":["state-file","json","corruption","sync"],"backgroundTag":"json-parse-error","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}