{"record":{"id":"9d33382889a5dad7","repo":"iBotPeaches/Apktool","slug":"could-not-copy-file","errorCode":null,"errorMessage":"Could not copy file: ","messagePattern":"Could not copy file: ","errorType":"exception","errorClass":"BrutException","httpStatus":null,"severity":"error","filePath":"brut.j.util/src/main/java/brut/util/OS.java","lineNumber":107,"sourceCode":"            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    }\n\n    public static void cpdir(String src, String dest) throws BrutException {\n        cpdir(new File(src), new File(dest));\n    }\n\n    public static void cpdir(File src, File dest) throws BrutException {\n        if (!src.isDirectory()) {\n            return;\n        }\n\n        mkdir(dest);\n\n        File[] files = src.listFiles();\n        if (files == null) {\n            return;\n        }","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/iBotPeaches/Apktool/blob/79b63384d7d7e22917e6ea8b453272da7012515b/brut.j.util/src/main/java/brut/util/OS.java#L89-L125","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the destination parent directory exists: dest.getParentFile().mkdirs() before the call","Verify writability early: dest.getParentFile() != null && dest.getParentFile().canWrite()","Check free space on the destination volume before large copies","Read the chained cause to distinguish permissions vs. missing directory vs. disk full"],"exampleFix":"// before\nOS.cpfile(src, dest); // dest dir may not exist\n\n// after\nFile parent = dest.getParentFile();\nif (parent != null && !parent.exists()) parent.mkdirs();\nOS.cpfile(src, dest);","handlingStrategy":"validation","validationCode":"boolean canCopy(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 (canCopy(src, dest)) OS.cpfile(src, dest);","typeGuard":null,"tryCatchPattern":"try {\n    OS.cpfile(src, dest);\n} catch (BrutException e) {\n    log.error(\"copy failed src={} dest={}\", src, dest, e.getCause());\n    throw e; // no silent skip: a skipped artifact corrupts the build output\n}","preventionTips":["Create output directories up front in one place instead of relying on copy targets to exist","Check free disk space before large batch copies","Note the API's silent no-op when src is not a file — verify src exists if a missing copy would be a bug"],"tags":["filesystem","io","copy","java"],"backgroundTag":null,"analyzedSha":"79b63384d7d7e22917e6ea8b453272da7012515b","analyzedAt":"2026-08-14T10:43:28.812Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}