nostra13/Android-Universal-Image-Loader · error · IllegalArgumentException
cacheMaxFileCount argument must be positive number
Error message
cacheMaxFileCount argument must be positive number
What it means
LruDiskCache's constructor throws IllegalArgumentException when cacheMaxFileCount is negative. As with cacheMaxSize, 0 is the documented 'unlimited' value (normalized to Integer.MAX_VALUE) and any negative count is rejected. The message wording ('must be positive number') is slightly off since 0 is legal.
Source
Thrown at library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/LruDiskCache.java:91
* @param cacheDir Directory for file caching
* @param reserveCacheDir null-ok; Reserve directory for file caching. It's used when the primary directory isn't available.
* @param fileNameGenerator {@linkplain com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator
* Name generator} for cached files. Generated names must match the regex
* <strong>[a-z0-9_-]{1,64}</strong>
* @param cacheMaxSize Max cache size in bytes. <b>0</b> means cache size is unlimited.
* @param cacheMaxFileCount Max file count in cache. <b>0</b> means file count is unlimited.
* @throws IOException if cache can't be initialized (e.g. "No space left on device")
*/
public LruDiskCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator, long cacheMaxSize,
int cacheMaxFileCount) throws IOException {
if (cacheDir == null) {
throw new IllegalArgumentException("cacheDir" + ERROR_ARG_NULL);
}
if (cacheMaxSize < 0) {
throw new IllegalArgumentException("cacheMaxSize" + ERROR_ARG_NEGATIVE);
}
if (cacheMaxFileCount < 0) {
throw new IllegalArgumentException("cacheMaxFileCount" + ERROR_ARG_NEGATIVE);
}
if (fileNameGenerator == null) {
throw new IllegalArgumentException("fileNameGenerator" + ERROR_ARG_NULL);
}
if (cacheMaxSize == 0) {
cacheMaxSize = Long.MAX_VALUE;
}
if (cacheMaxFileCount == 0) {
cacheMaxFileCount = Integer.MAX_VALUE;
}
this.reserveCacheDir = reserveCacheDir;
this.fileNameGenerator = fileNameGenerator;
initCache(cacheDir, reserveCacheDir, cacheMaxSize, cacheMaxFileCount);
}
private void initCache(File cacheDir, File reserveCacheDir, long cacheMaxSize, int cacheMaxFileCount)View on GitHub (pinned to ba33ec64d0)
Solutions
- Pass a positive count (e.g. 10000) or 0 for unlimited.
- Clamp computed counts with Math.max(0, n).
- Map sentinel values (-1) to 0 before construction.
Example fix
// before int count = quota - usedFiles; // negative when over quota new LruDiskCache(dir, null, gen, maxSize, count); // after int count = Math.max(0, quota - usedFiles); new LruDiskCache(dir, null, gen, maxSize, count);
Defensive patterns
Strategy: validation
Validate before calling
int countArg = (cacheMaxFileCount >= 0) ? cacheMaxFileCount : 0; // 0 == unlimited new LruDiskCache(dir, reserve, gen, maxSize, countArg);
Prevention
- Clamp count computations with Math.max(0, n).
- Don't forward -1 sentinel defaults from config objects into the constructor.
- 0 means unlimited; pick a positive number like 10000 for a bounded file count.
When it happens
Trigger: Calling new LruDiskCache(cacheDir, reserve, generator, maxSize, -1) or any negative count, e.g. from .diskCacheFileCount(-1) style configuration or a count computed as (limit - current) that underflowed.
Common situations: Using -1 as an 'unset' default in config objects and forwarding it directly; unit tests passing sentinel values; refactors that changed the parameter's type/order.
Related errors
- maxSize <= 0
- cacheMaxSize argument must be positive number
- maxFileCount <= 0
- valueCount <= 0
- cacheDir argument must be not null
AI-assisted analysis of nostra13/Android-Universal-Image-Loader@ba33ec64d0 (2026-08-14).
Data as JSON: /api/errors/b3619bd92e69dc86.
Report an issue: GitHub.