skylot/jadx · error · JadxRuntimeException
Failed to write caches file
Error message
Failed to write caches file
What it means
CacheManager.saveCaches serializes the in-memory cache entry list to JSON and writes it to the CACHES_LIST file with CREATE+TRUNCATE_EXISTING. If writing fails (disk full, permission denied, I/O error), a JadxRuntimeException wraps the cause.
Source
Thrown at jadx-gui/src/main/java/jadx/gui/cache/manager/CacheManager.java:220
if (Utils.isEmpty(list)) {
return new HashMap<>();
}
Map<String, CacheEntry> map = new HashMap<>(list.size());
for (CacheEntry entry : list) {
map.put(entry.getProject(), entry);
}
return map;
}
private synchronized void saveCaches(Map<String, CacheEntry> map) {
List<CacheEntry> list = new ArrayList<>(map.values());
Collections.sort(list);
String json = GSON.toJson(list, CACHES_TYPE);
try {
Files.writeString(JadxFiles.CACHES_LIST, json, StandardCharsets.UTF_8,
StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} catch (Exception e) {
throw new JadxRuntimeException("Failed to write caches file", e);
}
}
/**
* Load caches info from recent projects list.
* Help for initial migration.
*/
private Map<String, CacheEntry> initFromRecentProjects() {
try {
Map<String, CacheEntry> map = new HashMap<>();
long t = System.currentTimeMillis();
for (Path project : settings.getRecentProjects()) {
try {
ProjectData data = JadxProject.loadProjectData(project);
String cacheDir = data.getCacheDir();
if (cacheDir == null) {
// no cache dir, ignore
continue;View on GitHub (pinned to e738a26571)
Solutions
- Free disk space in the user home / config directory
- Check write permissions on the jadx configuration directory
- Ensure only one jadx instance is running
- Add an antivirus/sync exclusion for the jadx config directory
- Manually delete the caches list file to force recreation
Example fix
// Clear the caches list to allow clean recreation: // rm ~/.jadx/caches.json (path varies by OS / config) // Restart jadx — it will recreate the file.
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify config dir is writable before saving
Path cachesList = JadxFiles.CACHES_LIST;
Files.createDirectories(cachesList.getParent());
if (!Files.isWritable(cachesList.getParent())) { throw new IllegalStateException("Cannot write caches file"); } Try / catch
try {
cacheManager.saveCaches(map);
} catch (JadxRuntimeException e) {
if (e.getMessage().contains("Failed to write caches file")) {
LOG.warn("Non-fatal: could not persist cache list", e);
// in-memory state is still valid
}
} Prevention
- Keep the config directory writable and on local storage
- Run a single jadx instance
- Treat caches-list write failure as non-fatal
When it happens
Trigger: saveCaches() builds a sorted list of CacheEntry, serializes via Gson, and calls Files.writeString. Any exception during write triggers the error. Called during cache lifecycle updates (adding, removing, or verifying cache entries).
Common situations: Disk full or quota exceeded in the user configuration directory. Permission denied on the caches list file. Concurrent write from two jadx instances. Antivirus or sync software locking the file. Read-only filesystem.
Related errors
- Failed to write metadata file
- Failed to parse code annotations
- Failed to reset code cache
- Failed to remove code cache for {}
- Failed to enumerate cached classes
AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14).
Data as JSON: /api/errors/b10153a736993b6d.
Report an issue: GitHub.