{"record":{"id":"ad42e023a9b20a0e","repo":"nostra13/Android-Universal-Image-Loader","slug":"newly-created-entry-didn-t-create-value-for-index","errorCode":null,"errorMessage":"Newly created entry didn't create value for index {i}","messagePattern":"Newly created entry didn't create value for index (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/DiskLruCache.java","lineNumber":545,"sourceCode":"\t * this cache. This may be greater than the max file count if a background\n\t * deletion is pending.\n\t */\n\tpublic synchronized long fileCount() {\n\t\treturn fileCount;\n\t}\n\n\tprivate synchronized void completeEdit(Editor editor, boolean success) throws IOException {\n\t\tEntry entry = editor.entry;\n\t\tif (entry.currentEditor != editor) {\n\t\t\tthrow new IllegalStateException();\n\t\t}\n\n\t\t// If this edit is creating the entry for the first time, every index must have a value.\n\t\tif (success && !entry.readable) {\n\t\t\tfor (int i = 0; i < valueCount; i++) {\n\t\t\t\tif (!editor.written[i]) {\n\t\t\t\t\teditor.abort();\n\t\t\t\t\tthrow new IllegalStateException(\"Newly created entry didn't create value for index \" + i);\n\t\t\t\t}\n\t\t\t\tif (!entry.getDirtyFile(i).exists()) {\n\t\t\t\t\teditor.abort();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (int i = 0; i < valueCount; i++) {\n\t\t\tFile dirty = entry.getDirtyFile(i);\n\t\t\tif (success) {\n\t\t\t\tif (dirty.exists()) {\n\t\t\t\t\tFile clean = entry.getCleanFile(i);\n\t\t\t\t\tdirty.renameTo(clean);\n\t\t\t\t\tlong oldLength = entry.lengths[i];\n\t\t\t\t\tlong newLength = clean.length();\n\t\t\t\t\tentry.lengths[i] = newLength;\n\t\t\t\t\tsize = size - oldLength + newLength;","sourceCodeStart":527,"sourceCodeEnd":563,"githubUrl":"https://github.com/nostra13/Android-Universal-Image-Loader/blob/ba33ec64d0daaa881d35852460e78c58d086bc18/library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/DiskLruCache.java#L527-L563","documentation":"IllegalStateException from DiskLruCache.completeEdit: when an edit succeeds on an entry that has never been committed (not yet readable), every one of the valueCount files must have been written. If editor.written[i] is false for any index, the edit is aborted and this is thrown — the caller committed an editor without writing all values. In this library valueCount is always 1, so it means the single value file was never written before commit().","triggerScenarios":"Calling editor.commit() (or DiskLruCache.edit succeeding internally) without ever obtaining/creating the value file: e.g. getting an Editor via cache.edit(key), skipping newOutputStream(0)/file(0) writes entirely (for instance the download failed and you still commit), then committing success=true on a brand-new entry.","commonSituations":"Custom code on top of DiskLruCache that commits 'successfully' on an empty/failed download path; races where the value write was skipped because a stream could not be opened; misunderstandings that commit() on an unwritten new entry is a no-op.","solutions":["Only call editor.commit() after the value(s) were actually written; call editor.abort() on any failure path.","Structure saves as: edit -> write ALL value files -> commit; wrap in try/finally that aborts on exception.","If you use LruDiskCache.save() directly, ensure the incoming InputStream is fully copied before it returns success."],"exampleFix":"// before\nEditor editor = cache.edit(key);\n// download failed, but commit anyway\neditor.commit(); // IllegalStateException on new entry\n\n// after\nEditor editor = cache.edit(key);\nif (editor == null) return false;\ntry {\n    boolean ok = copyStream inputStream -> editor.newOutputStream(0); // writes index 0\n    if (!ok) { editor.abort(); return false; }\n    editor.commit();\n} catch (IOException e) {\n    editor.abort();\n    throw e;\n}","handlingStrategy":"validation","validationCode":"Editor editor = cache.edit(key);\nif (editor == null) return false; // entry being edited elsewhere\nboolean allWritten = false;\ntry {\n    OutputStream os = editor.newOutputStream(0);\n    allWritten = copyStream(source, os, buffer); // writes every value index (here: just 0)\n} finally {\n    if (allWritten) editor.commit(); else editor.abort();\n}","typeGuard":null,"tryCatchPattern":"try {\n    writeAllValues(editor);\n    editor.commit();\n} catch (Exception e) {\n    editor.abort(); // leave entry consistent instead of throwing IllegalState later\n    throw e;\n}","preventionTips":["Rule: commit() only after every value file was written; abort() on every failure path.","Use try/finally so abort() runs even when the stream copy throws.","valueCount is 1 in this library — but keep the discipline generic: write index 0 always."],"tags":["disk-cache","lru","editor-lifecycle","state-machine","illegal-state"],"backgroundTag":null,"analyzedSha":"ba33ec64d0daaa881d35852460e78c58d086bc18","analyzedAt":"2026-08-14T15:41:15.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}