nostra13/Android-Universal-Image-Loader · error · IllegalStateException

Newly created entry didn't create value for index {i}

Error message

Newly created entry didn't create value for index {i}

What it means

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().

Source

Thrown at library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/DiskLruCache.java:545

	 * this cache. This may be greater than the max file count if a background
	 * deletion is pending.
	 */
	public synchronized long fileCount() {
		return fileCount;
	}

	private synchronized void completeEdit(Editor editor, boolean success) throws IOException {
		Entry entry = editor.entry;
		if (entry.currentEditor != editor) {
			throw new IllegalStateException();
		}

		// If this edit is creating the entry for the first time, every index must have a value.
		if (success && !entry.readable) {
			for (int i = 0; i < valueCount; i++) {
				if (!editor.written[i]) {
					editor.abort();
					throw new IllegalStateException("Newly created entry didn't create value for index " + i);
				}
				if (!entry.getDirtyFile(i).exists()) {
					editor.abort();
					return;
				}
			}
		}

		for (int i = 0; i < valueCount; i++) {
			File dirty = entry.getDirtyFile(i);
			if (success) {
				if (dirty.exists()) {
					File clean = entry.getCleanFile(i);
					dirty.renameTo(clean);
					long oldLength = entry.lengths[i];
					long newLength = clean.length();
					entry.lengths[i] = newLength;
					size = size - oldLength + newLength;

View on GitHub (pinned to ba33ec64d0)

Solutions

  1. Only call editor.commit() after the value(s) were actually written; call editor.abort() on any failure path.
  2. Structure saves as: edit -> write ALL value files -> commit; wrap in try/finally that aborts on exception.
  3. If you use LruDiskCache.save() directly, ensure the incoming InputStream is fully copied before it returns success.

Example fix

// before
Editor editor = cache.edit(key);
// download failed, but commit anyway
editor.commit(); // IllegalStateException on new entry

// after
Editor editor = cache.edit(key);
if (editor == null) return false;
try {
    boolean ok = copyStream inputStream -> editor.newOutputStream(0); // writes index 0
    if (!ok) { editor.abort(); return false; }
    editor.commit();
} catch (IOException e) {
    editor.abort();
    throw e;
}
Defensive patterns

Strategy: validation

Validate before calling

Editor editor = cache.edit(key);
if (editor == null) return false; // entry being edited elsewhere
boolean allWritten = false;
try {
    OutputStream os = editor.newOutputStream(0);
    allWritten = copyStream(source, os, buffer); // writes every value index (here: just 0)
} finally {
    if (allWritten) editor.commit(); else editor.abort();
}

Try / catch

try {
    writeAllValues(editor);
    editor.commit();
} catch (Exception e) {
    editor.abort(); // leave entry consistent instead of throwing IllegalState later
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of nostra13/Android-Universal-Image-Loader@ba33ec64d0 (2026-08-14). Data as JSON: /api/errors/ad42e023a9b20a0e. Report an issue: GitHub.