spring-projects/spring-ai · error · RuntimeException
Failed to commit changes to index for session:
Error message
Failed to commit changes to index for session:
What it means
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.
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
Example fix
// before
index.add(sessionId, id, name, desc);
index.commit(); // RuntimeException when disk full or session concurrently cleared
// after
try {
index.add(sessionId, id, name, desc);
index.commit();
}
catch (RuntimeException e) {
logger.error("commit failed for index dir " + indexDir, e);
// check disk space / re-init session, then re-add and retry
} Defensive patterns
Strategy: try-catch
Validate before calling
File indexDir = new File(configuredPath);
if (!Files.isWritable(indexDir.toPath()) || indexDir.getUsableSpace() < 50L * 1024 * 1024) {
throw new IllegalStateException("Index directory not writable or low on disk: " + configuredPath);
} Try / catch
try {
index.commit();
}
catch (RuntimeException e) {
Throwable cause = e.getCause();
if (cause instanceof java.io.IOException ioEx) {
// log sessionId + cause, check disk/permissions, re-init session before retry
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Failed to add document to index
- Failed to clear the index for session:
- Failed to delete document from index
- Failed to get index size for session:
- Failed to initialize Lucene index for session:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/fa1256a648d62b68.
Report an issue: GitHub.
Appendix: source
Thrown at spring-ai-tool-search-tool/src/main/java/org/springframework/ai/tool/toolsearch/index/lucene/LuceneToolIndex.java:209
}
catch (IOException e) {
throw new RuntimeException("Failed to add document to index", e);
}
}
/**
* Commits all pending changes to all session indexes. Call this after batch additions
* for better performance.
*/
public void commit() {
for (Map.Entry<String, SessionIndex> entry : this.sessionIndexes.entrySet()) {
try {
SessionIndex sessionIndex = entry.getValue();
sessionIndex.writer.commit();
sessionIndex.refreshReader();
}
catch (IOException e) {
throw new RuntimeException("Failed to commit changes to index for session: " + entry.getKey(), e);
}
}
}
/**
* Commits all pending changes to the index for the specified session. Call this after
* batch additions for better performance.
* @param sessionId the session ID to commit changes for
*/
public void commit(String sessionId) {
SessionIndex sessionIndex = this.sessionIndexes.get(sessionId);
if (sessionIndex != null) {
try {
sessionIndex.writer.commit();
sessionIndex.refreshReader();
}
catch (IOException e) {
throw new RuntimeException("Failed to commit changes to index for session: " + sessionId, e);View on GitHub (pinned to 98a7beda4f)