{"record":{"id":"45f9ecf56592f5d5","repo":"rohitg00/agentmemory","slug":"agentmemory-failed-to-load-persisted-index","errorCode":null,"errorMessage":"[agentmemory] Failed to load persisted index:","messagePattern":"\\[agentmemory\\] Failed to load persisted index:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/index.ts","lineNumber":404,"sourceCode":"  registerSmartSearchFunction(sdk, kv, hybridRanker);\n  setHybridRanker(hybridRanker);\n  registerRecentSearchesSweepFunction(sdk, kv);\n\n  registerApiTriggers(sdk, kv, secret, metricsStore, provider);\n  registerEventTriggers(sdk, kv);\n  registerMcpEndpoints(sdk, kv, secret);\n\n  const healthMonitor = registerHealthMonitor(sdk, kv);\n\n  const indexPersistence = new IndexPersistence(kv, bm25Index, vectorIndex);\n  // Wire the persistence hook so delete paths can flush BM25/vector\n  // index mutations to disk. Without this, an in-memory remove can be\n  // lost across a hard process exit and the persisted snapshot\n  // restores the deleted entry at next boot.\n  setIndexPersistence(indexPersistence);\n\n  const loaded = await indexPersistence.load().catch((err) => {\n    console.warn(`[agentmemory] Failed to load persisted index:`, err);\n    return null;\n  });\n  if (loaded?.bm25 && loaded.bm25.size > 0) {\n    bm25Index.restoreFrom(loaded.bm25);\n    bootLog(\n      `Loaded persisted BM25 index (${bm25Index.size} docs)`,\n    );\n  }\n  if (loaded?.vector && vectorIndex && loaded.vector.size > 0) {\n    // Persisted vectors carry whatever dimension the provider had when\n    // they were written. If the active provider declares a different\n    // dimension — or if the on-disk index contains a mix of dimensions\n    // (legacy indexes written before the live-API guard in this PR) —\n    // restoring would silently corrupt search: cosineSimilarity returns\n    // 0 on cross-dim pairs, so affected observations stop matching\n    // anything and recall degrades without an error. Walk every stored\n    // vector instead of trusting the first; refuse to load if anything\n    // is off.","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/rohitg00/agentmemory/blob/e04ba88819c365c9acf9d6661ea802143e728bd6/src/index.ts#L386-L422","documentation":"Startup warning from the agentmemory daemon's `main()`. `indexPersistence.load()` reads the persisted BM25/vector index snapshot; if it rejects (corrupt file, unreadable state, deserialization error), the promise is caught, the error is logged with `console.warn`, and load resolves to `null` so boot continues with an empty index. The daemon still starts; only search recall is degraded until a rebuild.","triggerScenarios":"Boot with a corrupted or partially-written `state_store.db` / index snapshot; state file permissions changed; schema change after an upgrade makes the old snapshot unparsable; disk I/O error while reading state.","commonSituations":"Upgrading agentmemory across versions with an old on-disk index; killing the process mid-save leaving a truncated snapshot; running as a different user so ./data is unreadable; disk-full conditions during previous saves.","solutions":["Read the logged `err` to see the concrete cause (deserialization vs permissions vs I/O)","Back up and remove/rename the persisted index/state files (./data) so a fresh snapshot is written, accepting a rebuild","Check file permissions/ownership of ./data and fix them","If triggered by a version upgrade, either downgrade or let the index rebuild from live data","Verify disk space and that no other process holds the SQLite file locked"],"exampleFix":"// before\n[agentmemory] Failed to load persisted index: Error: file is not a database\n// after\n$ mv data/state_store.db data/state_store.db.bak\n$ agentmemory start\nLoaded persisted BM25 index (0 docs)  # rebuilds from live observations","handlingStrategy":"try-catch","validationCode":"// before boot, sanity-check state files\nimport { existsSync, statSync } from \"node:fs\";\nif (existsSync(\"./data/state_store.db\") && statSync(\"./data/state_store.db\").size === 0) {\n  console.warn(\"Empty/corrupt state file — move it aside before starting\");\n}","typeGuard":"function isLoadedIndex(x: unknown): x is { bm25: { size: number }; vector?: { size: number; validateDimensions(d: number): { mismatches: unknown[] } } } {\n  return typeof x === \"object\" && x !== null && \"bm25\" in x;\n}","tryCatchPattern":"try {\n  const loaded = await indexPersistence.load();\n} catch (err) {\n  console.warn(`[agentmemory] Failed to load persisted index:`, err);\n  // proceed with empty index; schedule a rebuild\n}","preventionTips":["Avoid killing the daemon with SIGKILL mid-save; use graceful shutdown","Keep ./data owned by the same user that runs the daemon","Back up state_store.db before upgrading versions","Monitor disk space on the state volume"],"tags":["startup","persistence","sqlite","index"],"backgroundTag":"persisted-index-load-failed","analyzedSha":"e04ba88819c365c9acf9d6661ea802143e728bd6","analyzedAt":"2026-08-30T01:07:40.754Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}