{"record":{"id":"0bed708afae38537","repo":"rohitg00/agentmemory","slug":"agentmemory-failed-to-save-index-on-shutdown","errorCode":null,"errorMessage":"[agentmemory] Failed to save index on shutdown:","messagePattern":"\\[agentmemory\\] Failed to save index on shutdown:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/index.ts","lineNumber":616,"sourceCode":"\n  if (isConsolidationEnabled()) {\n    const consolidationTimer = setInterval(async () => {\n      try {\n        await sdk.trigger({ function_id: \"mem::consolidate-pipeline\", payload: {} });\n      } catch {}\n    }, consolidationIntervalMs);\n    consolidationTimer.unref();\n    bootLog(`Auto-consolidation: enabled (every ${consolidationIntervalMs / 60000}m)`);\n  }\n\n  const shutdown = async () => {\n    console.log(`\\n[agentmemory] Shutting down...`);\n    healthMonitor.stop();\n    dedupMap.stop();\n    indexPersistence.stop();\n    await new Promise<void>((resolve) => viewerServer.close(() => resolve()));\n    await indexPersistence.save().catch((err) => {\n      console.warn(`[agentmemory] Failed to save index on shutdown:`, err);\n    });\n    await sdk.shutdown();\n    clearWorkerPidfile();\n    process.exit(0);\n  };\n  process.on(\"SIGINT\", shutdown);\n  process.on(\"SIGTERM\", shutdown);\n}\n\nmain().catch((err) => {\n  console.error(`[agentmemory] Fatal:`, err);\n  process.exit(1);\n});\n","sourceCodeStart":598,"sourceCodeEnd":630,"githubUrl":"https://github.com/rohitg00/agentmemory/blob/e04ba88819c365c9acf9d6661ea802143e728bd6/src/index.ts#L598-L630","documentation":"On SIGINT/SIGTERM the daemon's shutdown handler stops health monitoring, dedup, persistence scheduling and the viewer server, then makes one final indexPersistence.save() to flush the BM25 index to disk. If that save rejects, the promise's .catch logs this warning; the shutdown continues (sdk.shutdown, pidfile cleanup, exit 0), so the process still exits cleanly but the latest index state may not be persisted. Next startup may need to rebuild the search index from KV.","triggerScenarios":"Raised in the shutdown() handler at src/index.ts:616 when `indexPersistence.save()` rejects — e.g. the state DB was already stopped/closed, the disk is full, or the SQLite write fails during the SIGINT/SIGTERM path.","commonSituations":"Ctrl+C while a prior write transaction is still in flight; disk-full or read-only filesystem on the host; indexPersistence.stop() having released resources the final save() still needs; container being killed with a short grace period.","solutions":["Check the logged `err` for disk-full (ENOSPC), read-only filesystem (EROFS), or EBUSY and free space / fix permissions.","Restart the daemon — on boot the search index is rebuilt/backfilled from KV, recovering any lost persistence.","If this fires on every shutdown, ensure indexPersistence.stop() ordering allows save() to run, or upgrade agentmemory where shutdown ordering is fixed.","Avoid hard kill (SIGKILL); give the container/process enough shutdown grace period for the final save."],"exampleFix":"// before\nawait indexPersistence.save().catch((err) => {\n  console.warn(`[agentmemory] Failed to save index on shutdown:`, err);\n});\n// after — retry once before giving up\nawait indexPersistence.save()\n  .catch(() => new Promise((r) => setTimeout(r, 250)))\n  .then(() => indexPersistence.save())\n  .catch((err) => console.warn(`[agentmemory] Failed to save index on shutdown:`, err));","handlingStrategy":"try-catch","validationCode":"import fs from 'node:fs';\n// before shutdown-critical work, ensure the save target is writable\ntry { fs.accessSync('./data', fs.constants.W_OK); } catch { console.error('data dir not writable — final save will fail'); }","typeGuard":null,"tryCatchPattern":"await indexPersistence.save().catch((err) => {\n  console.warn(`[agentmemory] Failed to save index on shutdown:`, err);\n  // index is rebuilt from KV on next boot, so no retry storm needed\n});","preventionTips":["Stop the daemon with SIGINT/SIGTERM (not SIGKILL) and give containers a generous terminationGracePeriod.","Monitor disk space where data/state_store.db lives.","Back up the state DB periodically so a failed final save never loses data.","Check shutdown logs after deploys to catch recurring save failures early."],"tags":["shutdown","persistence","sqlite","sigint","data-loss-risk"],"backgroundTag":"flush-on-shutdown-failed","analyzedSha":"e04ba88819c365c9acf9d6661ea802143e728bd6","analyzedAt":"2026-08-30T01:07:40.754Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}