{"record":{"id":"f696e9f400cabba9","repo":"karatelabs/karate","slug":"store-has-been-closed","errorCode":null,"errorMessage":"store has been closed","messagePattern":"store has been closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/match/DiskBackedList.java","lineNumber":179,"sourceCode":"        return JSONValue.toJSONString(item);\n    }\n\n    private static Object deserializeItem(String json) {\n        if (json == null || json.isEmpty() || \"null\".equals(json)) {\n            return null;\n        }\n        return JSONValue.parse(json);\n    }\n\n    @Override\n    public int size() {\n        return size;\n    }\n\n    @Override\n    public Object get(int index) {\n        if (closed) {\n            throw new IllegalStateException(\"store has been closed\");\n        }\n        if (index < 0 || index >= size) {\n            throw new IndexOutOfBoundsException(\"index: \" + index + \", size: \" + size);\n        }\n        try {\n            if (raf == null) {\n                raf = new RandomAccessFile(tempFile, \"r\");\n            }\n            long offset = lineOffsets.get(index);\n            raf.seek(offset);\n            String line = raf.readLine();\n            return deserializeItem(line);\n        } catch (IOException e) {\n            throw new RuntimeException(\"failed to read item at index \" + index, e);\n        }\n    }\n\n    @Override","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/match/DiskBackedList.java#L161-L197","documentation":"DiskBackedList.get() throws this IllegalStateException when the list's backing store has already been closed via close(). After close, the temp file and RandomAccessFile handles are released, so reads are rejected explicitly rather than failing obscurely. This is a use-after-close guard.","triggerScenarios":"Calling get(index) on a DiskBackedList after calling close(); using a list that was closed by a try-with-resources block or shutdown hook; sharing the list across threads where one thread closes while another reads.","commonSituations":"Returning a DiskBackedList from a method that used try-with-resources; closing in a finally block then iterating later; lifecycle bugs in large-result-set handling where results are lazily read from disk.","solutions":["Do not close the list until all reads (get/iterator) are complete","If you need the data after close, copy it into a regular List before closing","Restructure so the consumer owns the list lifecycle (close where it was created)","Guard concurrent access: ensure close happens only after all reader threads finish"],"exampleFix":"// before\ntry (DiskBackedList list = new DiskBackedList(...)) { fill(list); }\nreturn list; // closed!\n// after\nDiskBackedList list = new DiskBackedList(...);\nfill(list);\nreturn list; // caller closes","handlingStrategy":"try-catch","validationCode":"if (list instanceof DiskBackedList) {\n  // cannot query closed state publicly; ensure close happens after use\n  useList(list);\n  ((DiskBackedList) list).close();\n}","typeGuard":"boolean isClosed(DiskBackedList l) { try { l.size(); return false; } catch (IllegalStateException e) { return true; } }","tryCatchPattern":"try { return list.get(i); } catch (IllegalStateException e) { if (e.getMessage().equals(\"store has been closed\")) throw new IllegalStateException(\"read after close; keep list open until consumers finish\", e); throw e; }","preventionTips":["Close the list only after all reads complete","Never return a list managed by try-with-resources","Copy to an in-memory list if data must outlive the store","Document ownership of the list lifecycle"],"tags":["lifecycle","use-after-close","io","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}