iBotPeaches/Apktool · error · BrutException
Could not move file:
Error message
Could not move file:
What it means
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.
Source
Thrown at brut.j.util/src/main/java/brut/util/OS.java:91
for (File file : files) {
if (file.isDirectory()) {
rmdir(file);
} else {
rmfile(file);
}
}
rmfile(dir);
}
public static void mvfile(String src, String dest) throws BrutException {
mvfile(new File(src), new File(dest));
}
public static void mvfile(File src, File dest) throws BrutException {
try {
Files.move(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new BrutException("Could not move file: " + src, ex);
}
}
public static void cpfile(String src, String dest) throws BrutException {
cpfile(new File(src), new File(dest));
}
public static void cpfile(File src, File dest) throws BrutException {
if (!src.isFile()) {
return;
}
try {
Files.copy(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new BrutException("Could not copy file: " + src, ex);
}
}View on GitHub (pinned to 79b63384d7)
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
Example fix
// before
OS.mvfile(src, dest); // fails when dest's parent is missing
// after
File parent = dest.getParentFile();
if (parent != null && !parent.exists() && !parent.mkdirs()) {
throw new BrutException("Cannot create dir: " + parent);
}
OS.mvfile(src, dest); Defensive patterns
Strategy: validation
Validate before calling
boolean canMove(File src, File dest) {
if (!src.isFile()) return false;
File parent = dest.getParentFile();
return parent != null && (parent.exists() || parent.mkdirs()) && parent.canWrite();
}
// if (canMove(src, dest)) OS.mvfile(src, dest); else handle(); Try / catch
try {
OS.mvfile(src, dest);
} catch (BrutException e) {
IOException cause = (IOException) e.getCause();
if (cause != null && cause.getMessage() != null && cause.getMessage().contains("cross")) {
OS.cpfile(src, dest); new File(src).delete(); // copy+delete fallback for cross-FS
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Could not copy file:
- Mark not supported
- Absolute paths are not allowed
- Path traverses outside the base directory
- Could not delete tmp file:
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/5a5872d7a13acf1f.
Report an issue: GitHub.