{"record":{"id":"a71ccacec69b3c6f","repo":"skylot/jadx","slug":"resource-file-save-error","errorCode":null,"errorMessage":"Resource file save error","messagePattern":"Resource file save error","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java","lineNumber":105,"sourceCode":"\t\t\t\t} catch (Exception e) {\n\t\t\t\t\tLOG.warn(\"Resource '{}' not saved, got exception\", rc.getName(), e);\n\t\t\t\t}\n\t\t\t\treturn;\n\n\t\t\tdefault:\n\t\t\t\tLOG.warn(\"Resource '{}' not saved, unknown type\", rc.getName());\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate void saveResourceFile(ResourceFile resFile, File outFile) throws JadxException {\n\t\tResourcesLoader.decodeStream(resFile, (size, is) -> {\n\t\t\tPath target = outFile.toPath();\n\t\t\ttry {\n\t\t\t\tFiles.copy(is, target, StandardCopyOption.REPLACE_EXISTING);\n\t\t\t} catch (Exception e) {\n\t\t\t\tFiles.deleteIfExists(target); // delete partially written file\n\t\t\t\tthrow new JadxRuntimeException(\"Resource file save error\", e);\n\t\t\t}\n\t\t\treturn null;\n\t\t});\n\t}\n}\n","sourceCodeStart":87,"sourceCodeEnd":111,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java#L87-L111","documentation":"ResourcesSaver.saveResourceFile copies a decoded resource stream to disk via Files.copy. If the copy fails (disk full, permission denied, path invalid), the partially written file is deleted and a JadxRuntimeException wraps the underlying cause.","triggerScenarios":"saveResourceFile calls ResourcesLoader.decodeStream, then Files.copy(is, target, REPLACE_EXISTING). On any exception, Files.deleteIfExists removes the partial output and rethrows as JadxRuntimeException. This is the terminal step of resource extraction during APK decompilation/saving.","commonSituations":"Insufficient disk space for the output directory. Read-only or permission-restricted output path. Path too long on Windows. Antivirus locking files mid-write. Output directory does not exist despite makeDirs being expected to create it.","solutions":["Check available disk space and free space if low","Verify write permissions on the output directory","Shorten the output path or move it closer to the filesystem root","Temporarily disable antivirus or add an exclusion for the output dir","Ensure the output directory exists and is writable before starting"],"exampleFix":"// Before decompiling, verify the output location:\nPath out = Paths.get(\"/tmp/out\");\nFiles.createDirectories(out);\nif (!Files.isWritable(out)) {\n    throw new IllegalStateException(\"Output dir not writable: \" + out);\n}","handlingStrategy":"try-catch","validationCode":"// Verify output directory is writable with sufficient space\nPath outDir = Paths.get(outputPath);\nFiles.createDirectories(outDir);\nif (!Files.isWritable(outDir)) { throw new IOException(\"Output not writable\"); }\nif (outDir.toFile().getUsableSpace() < MIN_SPACE) { throw new IOException(\"Insufficient space\"); }","typeGuard":null,"tryCatchPattern":"try {\n    decompiler.save();\n} catch (JadxRuntimeException e) {\n    if (e.getMessage().contains(\"Resource file save error\")) {\n        LOG.error(\"Failed to save a resource: \" + e.getCause().getMessage(), e);\n        // continue — other resources may still save\n    }\n}","preventionTips":["Check disk space and write permissions before starting decompilation","Use short paths on Windows","Temporarily disable antivirus for the output directory","Catch JadxRuntimeException during save() to allow partial results"],"tags":["io","filesystem","resource-extraction","permissions","disk-space"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}