Anuken/Mindustry · error · RuntimeException
Cache file for asset {path} not found!
Error message
Cache file for asset {path} not found! What it means
DataAsset.getCacheFileNoNull returns the override cache file or the hash-indexed file from Vars.assetCache; if neither resolves (no override and hash absent from cache) it throws RuntimeException. Used when an asset is expected to be cached but the cache entry is missing.
Source
Thrown at core/src/mindustry/mod/data/DataAsset.java:63
return getType().folder + "/" + path;
}
/** @return for embedded assets, the data. Not implemented for non-embedded assets (use the cache file). */
public byte[] getData(){
throw new UnsupportedOperationException("Not implemented");
}
public boolean isAlwaysEmbedded(){
return getType().embedded;
}
public boolean isCached(){
return overrideCacheFile != null || (stringHash != null && Vars.assetCache.has(stringHash));
}
public Fi getCacheFileNoNull(){
Fi file = getCacheFile();
if(file == null) throw new RuntimeException("Cache file for asset " + path + " not found!");
return file;
}
public @Nullable Fi getCacheFile(){
return overrideCacheFile != null ? overrideCacheFile : Vars.assetCache.get(stringHash);
}
public void readFromZip(String path, Fi file){
if(isAlwaysEmbedded()) throw new UnsupportedOperationException("Always-embedded assets need custom implementations for reading.");
setPath(path);
updateData(file.readBytes());
}
/** Reads this asset in from a file on disk, and makes its hash point to the specified file, instead of a new one in the cache folder. Only used on the server. */
public void readOverride(String path, Fi file) throws IOException{
setPath(path);
setHash(file.sha256());
this.overrideCacheFile = file;View on GitHub (pinned to f695ad7e60)
Solutions
- Ensure the asset cache is built/downloaded before requesting the asset.
- Verify the asset's stringHash matches an existing cache entry.
- Re-acquire or regenerate the asset bundle.
- Confirm isCached() returns true before calling getCacheFileNoNull().
Example fix
// before
Fi f = asset.getCacheFileNoNull(); // throws if not cached
// after
if (asset.isCached()) {
Fi f = asset.getCacheFileNoNull();
} else {
// trigger cache generation / download first
} Defensive patterns
Strategy: validation
Validate before calling
// Only demand a cache file when one actually exists.
if(!asset.isCached()) {
throw new IllegalStateException("Asset not cached, cannot resolve file: " + asset.path);
}
Fi f = asset.getCacheFileNoNull(); Type guard
boolean assetResolvable(DataAsset a){ return a != null && a.isCached(); } Try / catch
try {
Fi f = asset.getCacheFileNoNull();
} catch(RuntimeException e) {
if(e.getMessage().startsWith("Cache file for asset")) { /* (re)build cache */ }
else throw e;
} Prevention
- Call isCached() before getCacheFileNoNull().
- Ensure the asset cache is generated/downloaded for the build.
- Re-verify hashes when content changes.
When it happens
Trigger: An asset is treated as cached but its stringHash is not present in the asset cache and no overrideCacheFile was set.
Common situations: Asset cache not generated/downloaded for the current build; hash mismatch after content changed; missing asset in a partial install; cache disabled or cleared.
Related errors
- Data must be exactly 32 bytes (length: ${data.length})
- Max image size exceeded
- SectorPresets must have a sector number.
- '${field.field.getName()}' in ${className} is missing! ${obj
- Patch must be a JSON object.
AI-assisted analysis of Anuken/Mindustry@f695ad7e60 (2026-08-14).
Data as JSON: /api/errors/c004320a4b89f827.
Report an issue: GitHub.