{"record":{"id":"fa1256a648d62b68","repo":"spring-projects/spring-ai","slug":"failed-to-commit-changes-to-index-for-session","errorCode":null,"errorMessage":"Failed to commit changes to index for session: ","messagePattern":"Failed to commit changes to index for session: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-tool-search-tool/src/main/java/org/springframework/ai/tool/toolsearch/index/lucene/LuceneToolIndex.java","lineNumber":209,"sourceCode":"\t\t}\n\t\tcatch (IOException e) {\n\t\t\tthrow new RuntimeException(\"Failed to add document to index\", e);\n\t\t}\n\t}\n\n\t/**\n\t * Commits all pending changes to all session indexes. Call this after batch additions\n\t * for better performance.\n\t */\n\tpublic void commit() {\n\t\tfor (Map.Entry<String, SessionIndex> entry : this.sessionIndexes.entrySet()) {\n\t\t\ttry {\n\t\t\t\tSessionIndex sessionIndex = entry.getValue();\n\t\t\t\tsessionIndex.writer.commit();\n\t\t\t\tsessionIndex.refreshReader();\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\tthrow new RuntimeException(\"Failed to commit changes to index for session: \" + entry.getKey(), e);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Commits all pending changes to the index for the specified session. Call this after\n\t * batch additions for better performance.\n\t * @param sessionId the session ID to commit changes for\n\t */\n\tpublic void commit(String sessionId) {\n\t\tSessionIndex sessionIndex = this.sessionIndexes.get(sessionId);\n\t\tif (sessionIndex != null) {\n\t\t\ttry {\n\t\t\t\tsessionIndex.writer.commit();\n\t\t\t\tsessionIndex.refreshReader();\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\tthrow new RuntimeException(\"Failed to commit changes to index for session: \" + sessionId, e);","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-tool-search-tool/src/main/java/org/springframework/ai/tool/toolsearch/index/lucene/LuceneToolIndex.java#L191-L227","documentation":"Thrown by LuceneToolIndex.commit() when the per-session IndexWriter.commit() or the subsequent refreshReader() fails with an IOException while committing pending changes across ALL session indexes. Lucene commit involves fsync-ing segments and writing segments_N to disk, so this error means persisted index state could not be finalized (or the reopened reader could not be refreshed) for at least one session.","triggerScenarios":"Calling the no-arg commit() after batch add() calls when the underlying disk is full, unwritable, or the index directory was deleted; an already-closed or corrupt IndexWriter; or an IOException while reopening the IndexReader (refreshReader) after a concurrent clearIndex() for the same session.","commonSituations":"Disk-full on the machine hosting the index directory; index directory on a network mount that dropped; container volumes remounted read-only; another process holding a write lock or deleting the index directory; the session's index cleared concurrently by another thread (the documented write-after-close race).","solutions":["Check free disk space and write permissions on the Lucene index directory, then retry commit()","Inspect the wrapped IOException (getCause()) to see whether the failure was in writer.commit() or refreshReader()","If the session index was concurrently cleared or closed, re-initialize the session (re-add documents) before committing again","If the index directory is corrupt, delete it and rebuild by re-adding all tools for that session","Avoid calling clearIndex() concurrently with commit() for the same session"],"exampleFix":"// before\nindex.add(sessionId, id, name, desc);\nindex.commit(); // RuntimeException when disk full or session concurrently cleared\n// after\ntry {\n    index.add(sessionId, id, name, desc);\n    index.commit();\n}\ncatch (RuntimeException e) {\n    logger.error(\"commit failed for index dir \" + indexDir, e);\n    // check disk space / re-init session, then re-add and retry\n}","handlingStrategy":"try-catch","validationCode":"File indexDir = new File(configuredPath);\nif (!Files.isWritable(indexDir.toPath()) || indexDir.getUsableSpace() < 50L * 1024 * 1024) {\n    throw new IllegalStateException(\"Index directory not writable or low on disk: \" + configuredPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n    index.commit();\n}\ncatch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof java.io.IOException ioEx) {\n        // log sessionId + cause, check disk/permissions, re-init session before retry\n    }\n}","preventionTips":["Monitor free disk space on the index directory and alert before it fills","Never call clearIndex() concurrently with commit() for the same session","Place the Lucene index on reliable local (not NFS) storage","Commit in batches after bulk adds, and retry with backoff on transient IO failures"],"tags":["lucene","io","commit","index","disk"],"backgroundTag":"file-write-failed","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}