{"record":{"id":"5a5872d7a13acf1f","repo":"iBotPeaches/Apktool","slug":"could-not-move-file","errorCode":null,"errorMessage":"Could not move file: ","messagePattern":"Could not move file: ","errorType":"exception","errorClass":"BrutException","httpStatus":null,"severity":"error","filePath":"brut.j.util/src/main/java/brut/util/OS.java","lineNumber":91,"sourceCode":"        for (File file : files) {\n            if (file.isDirectory()) {\n                rmdir(file);\n            } else {\n                rmfile(file);\n            }\n        }\n        rmfile(dir);\n    }\n\n    public static void mvfile(String src, String dest) throws BrutException {\n        mvfile(new File(src), new File(dest));\n    }\n\n    public static void mvfile(File src, File dest) throws BrutException {\n        try {\n            Files.move(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);\n        } catch (IOException ex) {\n            throw new BrutException(\"Could not move file: \" + src, ex);\n        }\n    }\n\n    public static void cpfile(String src, String dest) throws BrutException {\n        cpfile(new File(src), new File(dest));\n    }\n\n    public static void cpfile(File src, File dest) throws BrutException {\n        if (!src.isFile()) {\n            return;\n        }\n\n        try {\n            Files.copy(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);\n        } catch (IOException ex) {\n            throw new BrutException(\"Could not copy file: \" + src, ex);\n        }\n    }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.j.util/src/main/java/brut/util/OS.java#L73-L109","documentation":"Thrown by OS.mvfile when java.nio.Files.move(src, dest, REPLACE_EXISTING) throws IOException. Files.move fails when the source does not exist, the destination's parent directory does not exist, the destination is a non-empty directory, a file is locked (Windows), or an atomic move is required across filesystems (this call is non-atomic but can still fail across stores on some platforms). The BrutException message includes the source path; the original IOException is attached as the cause.","triggerScenarios":"OS.mvfile(src, dest) where src is missing, dest.getParentFile() does not exist or is not writable, dest is an open/locked file (Windows), or src and dest live on different mounts/filesystems.","commonSituations":"Renaming decoded apk artifacts into a build output directory that was never mkdir'd; moving files across partitions (tmpfs to disk); antivirus or another process holding the destination on Windows; races where the source was already moved/consumed; two threads moving the same file.","solutions":["Create the destination parent first: dest.getParentFile() != null && (dest.getParentFile().exists() || dest.getParentFile().mkdirs())","Check src.isFile() before calling, or treat a missing source as a no-op if the move is idempotent in your flow","For cross-filesystem moves, fall back to copy-then-delete: Files.copy then Files.delete (or OS.cpfile + delete) when Files.move throws","Inspect the wrapped cause (ex.getCause()) to distinguish permission/lock failures from missing-path failures"],"exampleFix":"// before\nOS.mvfile(src, dest); // fails when dest's parent is missing\n\n// after\nFile parent = dest.getParentFile();\nif (parent != null && !parent.exists() && !parent.mkdirs()) {\n    throw new BrutException(\"Cannot create dir: \" + parent);\n}\nOS.mvfile(src, dest);","handlingStrategy":"validation","validationCode":"boolean canMove(File src, File dest) {\n    if (!src.isFile()) return false;\n    File parent = dest.getParentFile();\n    return parent != null && (parent.exists() || parent.mkdirs()) && parent.canWrite();\n}\n// if (canMove(src, dest)) OS.mvfile(src, dest); else handle();","typeGuard":null,"tryCatchPattern":"try {\n    OS.mvfile(src, dest);\n} catch (BrutException e) {\n    IOException cause = (IOException) e.getCause();\n    if (cause != null && cause.getMessage() != null && cause.getMessage().contains(\"cross\")) {\n        OS.cpfile(src, dest); new File(src).delete(); // copy+delete fallback for cross-FS\n    } else throw e;\n}","preventionTips":["mkdirs() the destination parent before every move","Remember REPLACE_EXISTING only replaces files — a non-empty dest directory still fails","On Windows, ensure no reader/AV holds the destination before moving over it"],"tags":["filesystem","io","move","java"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}