{"record":{"id":"4e3687872592afb0","repo":"spring-projects/spring-ai","slug":"failed-to-get-index-size-for-session","errorCode":null,"errorMessage":"Failed to get index size for session: ","messagePattern":"Failed to get index size 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":315,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Returns the number of documents in the index for the specified session.\n\t * @param sessionId the session ID\n\t * @return document count, or 0 if session not found\n\t */\n\tpublic int size(String sessionId) {\n\t\tSessionIndex sessionIndex = this.sessionIndexes.get(sessionId);\n\t\tif (sessionIndex == null) {\n\t\t\treturn 0;\n\t\t}\n\t\ttry {\n\t\t\treturn sessionIndex.ensureAndGetReader().numDocs();\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tthrow new RuntimeException(\"Failed to get index size for session: \" + sessionId, e);\n\t\t}\n\t}\n\n\t/**\n\t * Returns the total number of documents across all session indexes.\n\t * @return total document count\n\t */\n\tpublic int totalSize() {\n\t\tint total = 0;\n\t\tfor (String sessionId : this.sessionIndexes.keySet()) {\n\t\t\ttotal += size(sessionId);\n\t\t}\n\t\treturn total;\n\t}\n\n\t@Override\n\tpublic void close() throws IOException {\n\t\tfor (SessionIndex sessionIndex : this.sessionIndexes.values()) {","sourceCodeStart":297,"sourceCodeEnd":333,"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#L297-L333","documentation":"Thrown by LuceneToolIndex.size(sessionId) when ensureAndGetReader() throws an IOException while reopening or accessing the session's IndexReader to report numDocs(). Unlike search or commit, this is only a read-only operation, so it almost always means the index directory or segment files are missing, unreadable, or corrupt. Note: an unknown sessionId returns 0 instead of throwing — only a known session whose reader cannot be opened raises this error.","triggerScenarios":"Calling size() (or totalSize(), which iterates size() for every session) after the index directory was deleted or made unreadable, the on-disk index is corrupt, or the reader reopen fails due to I/O errors on the storage backing the index.","commonSituations":"External cleanup job or deployment wiping the index directory while the app holds sessions; read-only remount in containers; corrupted segments after a crash mid-commit; totalSize() sweeping many sessions so one bad session index fails the whole count; network storage with stale NFS file handles.","solutions":["Inspect the wrapped IOException cause to identify which session index file/operation failed","Verify the session's index directory exists and is readable by the process","If the index directory is gone or corrupt, re-initialize the session by re-adding its tools","Iterate sessions with try-catch around size(sessionId) in your own totalSize-like logic so one bad session does not break the aggregate","Check storage health (disk, NFS mounts, container volumes) backing the index directory"],"exampleFix":"// before\nint count = index.totalSize(); // one unreadable session index fails the whole sweep\n// after\nint count = 0;\nfor (String sessionId : sessionIds) {\n    try {\n        count += index.size(sessionId);\n    }\n    catch (RuntimeException e) {\n        logger.warn(\"size failed for session \" + sessionId + \", counting as 0\", e);\n    }\n}","handlingStrategy":"try-catch","validationCode":"File idxDir = new File(indexPath);\nif (!idxDir.isDirectory() || !Files.isReadable(idxDir.toPath())) {\n    throw new IllegalStateException(\"Session index directory missing/unreadable: \" + indexPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n    int n = index.size(sessionId);\n}\ncatch (RuntimeException e) {\n    if (e.getCause() instanceof java.io.IOException) {\n        logger.warn(\"cannot read index size for session \" + sessionId + \", treating as 0\", e);\n    }\n    // treat as 0 and trigger session re-initialization if needed\n}","preventionTips":["Verify the index directory exists and is readable before reading index stats","Guard aggregate sweeps (totalSize-like logic) so one bad session does not fail them all","Watch for external cleanup jobs or deploys wiping the index directory while the app runs","Use local disk rather than network mounts for Lucene index storage"],"tags":["lucene","io","index","reader","filesystem"],"backgroundTag":"file-read-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"}