skylot/jadx · error · RuntimeException
Failed to write metadata file
Error message
Failed to write metadata file
What it means
CodeMetadataAdapter.write serializes code metadata (line mappings and annotations) to a .jadxmd file using a DataOutputStream. If any IO or serialization error occurs during writing, it is wrapped in a RuntimeException. This is part of jadx-gui's disk code cache for faster subsequent decompilation.
Source
Thrown at jadx-gui/src/main/java/jadx/gui/cache/code/disk/CodeMetadataAdapter.java:50
public class CodeMetadataAdapter {
private static final byte[] JADX_METADATA_HEADER = "jadxmd".getBytes(StandardCharsets.US_ASCII);
private final CodeAnnotationAdapter codeAnnotationAdapter;
public CodeMetadataAdapter(RootNode root) {
codeAnnotationAdapter = new CodeAnnotationAdapter(root);
}
public void write(Path metadataFile, ICodeMetadata metadata) {
FileUtils.makeDirsForFile(metadataFile);
try (OutputStream fileOutput = Files.newOutputStream(metadataFile, WRITE, CREATE, TRUNCATE_EXISTING);
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fileOutput))) {
out.write(JADX_METADATA_HEADER);
writeLines(out, metadata.getLineMapping());
writeAnnotations(out, metadata.getAsMap());
} catch (Exception e) {
throw new RuntimeException("Failed to write metadata file", e);
}
}
public ICodeInfo readAndBuild(Path metadataFile, String code) {
if (!Files.exists(metadataFile)) {
return new SimpleCodeInfo(code);
}
try (InputStream fileInput = Files.newInputStream(metadataFile);
DataInputStream in = new DataInputStream(new BufferedInputStream(fileInput))) {
in.skipBytes(JADX_METADATA_HEADER.length);
Map<Integer, Integer> lines = readLines(in);
Map<Integer, ICodeAnnotation> annotations = readAnnotations(in);
return new AnnotatedCodeInfo(code, lines, annotations);
} catch (Exception e) {
throw new RuntimeException("Failed to parse code annotations", e);
}
}
View on GitHub (pinned to e738a26571)
Solutions
- Free disk space in the cache directory (typically under the user home or temp)
- Check permissions on the jadx cache directory
- Clear the jadx cache directory to reset state
- Reduce the number of classes or disable code caching in jadx settings
Example fix
// Clear the cache directory manually: // Linux/Mac: rm -rf ~/.jadx/cache // Or in jadx-gui: File > Clear Cache // No API code fix needed — this is an internal cache write.
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure cache directory is writable and has space before starting
Path cacheDir = JadxFiles.CACHE_DIR;
Files.createDirectories(cacheDir);
if (!Files.isWritable(cacheDir)) { throw new IllegalStateException("Cache dir not writable"); } Try / catch
// Internal to jadx-gui; no caller API. Clear cache on failure: // catch is inside DiskCodeCache; user action is to clear the cache dir.
Prevention
- Keep the cache directory on a local disk with free space
- Clear the cache periodically or after jadx upgrades
- Avoid running multiple jadx instances sharing one cache
When it happens
Trigger: write() opens the metadata file with CREATE+TRUNCATE_EXISTING, writes a header and line/annotation maps. Any exception (disk full, permission error, serialization failure) triggers the RuntimeException. Called by DiskCodeCache's async write pool during background caching.
Common situations: Disk full or quota exceeded in the cache directory. Permission issues in the user's cache directory. Concurrent file access or locking. Corrupted cache state from a previous interrupted write. JVM running out of memory during large annotation serialization.
Related errors
- Failed to write caches 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/d6f7994b75d0e472.
Report an issue: GitHub.