iBotPeaches/Apktool · error · BrutException

Could not copy file:

Error message

Could not copy file: 

What it means

Thrown by OS.cpfile when Files.copy(src, dest, REPLACE_EXISTING) throws IOException. Note the method silently returns when src.isFile() is false, so this error only fires when the source exists as a file but the copy itself fails: destination parent missing, permission denied, destination is a directory, or disk full. The cause IOException is chained and the source path is included in the message.

Source

Thrown at brut.j.util/src/main/java/brut/util/OS.java:107

            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);
        }
    }

    public static void cpdir(String src, String dest) throws BrutException {
        cpdir(new File(src), new File(dest));
    }

    public static void cpdir(File src, File dest) throws BrutException {
        if (!src.isDirectory()) {
            return;
        }

        mkdir(dest);

        File[] files = src.listFiles();
        if (files == null) {
            return;
        }

View on GitHub (pinned to 79b63384d7)

Solutions

  1. Ensure the destination parent directory exists: dest.getParentFile().mkdirs() before the call
  2. Verify writability early: dest.getParentFile() != null && dest.getParentFile().canWrite()
  3. Check free space on the destination volume before large copies
  4. Read the chained cause to distinguish permissions vs. missing directory vs. disk full

Example fix

// before
OS.cpfile(src, dest); // dest dir may not exist

// after
File parent = dest.getParentFile();
if (parent != null && !parent.exists()) parent.mkdirs();
OS.cpfile(src, dest);
Defensive patterns

Strategy: validation

Validate before calling

boolean canCopy(File src, File dest) {
    if (!src.isFile()) return false;
    File parent = dest.getParentFile();
    return parent != null && (parent.exists() || parent.mkdirs()) && parent.canWrite();
}
// if (canCopy(src, dest)) OS.cpfile(src, dest);

Try / catch

try {
    OS.cpfile(src, dest);
} catch (BrutException e) {
    log.error("copy failed src={} dest={}", src, dest, e.getCause());
    throw e; // no silent skip: a skipped artifact corrupts the build output
}

Prevention

When it happens

Trigger: OS.cpfile(src, dest) where src is a regular file but dest.getParentFile() does not exist, the destination path already exists as a non-empty directory, the process lacks write permission on the destination directory, or the target volume has no space.

Common situations: Copying decoded/intermediate apk files into an output folder that was never created; running with restricted permissions (containers, read-only mounts); destination locked by another process on Windows; disk exhaustion during large asset copies.

Related errors


AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14). Data as JSON: /api/errors/9d33382889a5dad7. Report an issue: GitHub.