Blankj/AndroidUtilCode · error · IllegalArgumentException
{} > {}
Error message
{} > {} What it means
Thrown by CacheDiskUtils$cacheInner.copyOfRange when the 'from' argument exceeds 'to' (i.e., newLength = to - from < 0). This is a defensive guard mirroring java.util.Arrays.copyOfRange semantics, protecting the subsequent array allocation from a negative length. It indicates corrupted or unexpected time-info header parsing in the on-disk cache byte payload.
Source
Thrown at lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java:860
try {
return Long.parseLong(millis) * 1000;
} catch (NumberFormatException e) {
return -1;
}
}
return -1;
}
private static byte[] getDataWithoutDueTime(final byte[] data) {
if (hasTimeInfo(data)) {
return copyOfRange(data, TIME_INFO_LEN, data.length);
}
return data;
}
private static byte[] copyOfRange(final byte[] original, final int from, final int to) {
int newLength = to - from;
if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
byte[] copy = new byte[newLength];
System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
return copy;
}
private static boolean hasTimeInfo(final byte[] data) {
return data != null
&& data.length >= TIME_INFO_LEN
&& data[0] == '_'
&& data[1] == '$'
&& data[12] == '$'
&& data[13] == '_';
}
}
}View on GitHub (pinned to 7b4caf9e54)
Solutions
- Clear the affected cache entry/directory so the malformed payload is regenerated.
- Ensure cache writes are atomic (write to temp then rename) to avoid truncated entries.
- Verify the utilcode version matches the version that wrote the cache (TIME_INFO_LEN is version-specific).
- Wrap cache reads in a try/catch and treat a malformed entry as a cache miss.
Example fix
// before
byte[] payload = cacheDiskUtils.getBytes(key); // from > to on corrupted entry
// after
byte[] payload;
try {
payload = cacheDiskUtils.getBytes(key);
} catch (IllegalArgumentException ex) {
cacheDiskUtils.remove(key); // drop the corrupted entry
payload = null;
} Defensive patterns
Strategy: try-catch
Validate before calling
// No caller-side validation fully prevents this (corruption is on disk). // Best pre-check: confirm utilcode version matches the cache writer's version // and that cache writes are atomic (write-to-temp + rename).
Try / catch
byte[] payload;
try {
payload = cacheDiskUtils.getBytes(key);
} catch (IllegalArgumentException e) {
// malformed time-info header -> treat as cache miss
cacheDiskUtils.remove(key);
payload = null;
} Prevention
- Write cache entries atomically (temp file + rename) to avoid truncated headers.
- Clear the cache directory when upgrading utilcode versions that change TIME_INFO_LEN.
- Treat any cache read exception as a soft miss, not a fatal error.
- Avoid concurrent uncontrolled writes to the same cache directory.
When it happens
Trigger: The cache data's time-info header (the '_$...$_' marker) reports a TIME_INFO_LEN start offset greater than the total data length, so copyOfRange(data, TIME_INFO_LEN, data.length) is called with from > to. Happens during getDataWithoutDueTime when hasTimeInfo returned true for a malformed/truncated entry.
Common situations: Disk-cache corruption (partial writes, app killed mid-write); cache format migration between utilcode versions where TIME_INFO_LEN changed; manually editing or truncating cache files; concurrent access to the cache directory without locking.
Related errors
- Not an array: {}
- Array has incompatible type: {}
- Unsupported object type: {}
- segment of <{segment}> is illegal
- Index: {}, array1 Length: {}
AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14).
Data as JSON: /api/errors/779ce8ed27dded26.
Report an issue: GitHub.