{"record":{"id":"ed2a2981f1c31394","repo":"eclipse-vertx/vert.x","slug":"failed-to-copy-from-to-to","errorCode":null,"errorMessage":"Failed to copy ${from} to ${to}","messagePattern":"Failed to copy (.+?) to (.+?)","errorType":"exception","errorClass":"FileSystemException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java","lineNumber":425,"sourceCode":"\n  static String getFileDualOperationErrorMessage(String action, String from, String to) {\n    return \"Unable to \" + action + \" file from '\" + from + \"' to '\" + to + \"'\";\n  }\n\n  private BlockingAction<Void> copyInternal(String from, String to, CopyOptions options) {\n    Objects.requireNonNull(from);\n    Objects.requireNonNull(to);\n    Objects.requireNonNull(options);\n    Set<CopyOption> copyOptionSet = toCopyOptionSet(options);\n    CopyOption[] copyOptions = copyOptionSet.toArray(new CopyOption[0]);\n    return new BlockingAction<Void>() {\n      public Void perform() {\n        try {\n          Path source = resolveFile(from).toPath();\n          Path target = resolveFile(to).toPath();\n          Files.copy(source, target, copyOptions);\n        } catch (IOException e) {\n          throw new FileSystemException(getFileCopyErrorMessage(from, to), e);\n        }\n        return null;\n      }\n    };\n  }\n\n  private BlockingAction<Void> copyRecursiveInternal(String from, String to, boolean recursive) {\n    Objects.requireNonNull(from);\n    Objects.requireNonNull(to);\n    return new BlockingAction<Void>() {\n      public Void perform() {\n        try {\n          Path source = resolveFile(from).toPath();\n          Path target = resolveFile(to).toPath();\n          if (recursive) {\n            Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,\n              new SimpleFileVisitor<Path>() {\n                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java#L407-L443","documentation":"The blocking copy action in FileSystemImpl (simple, non-recursive variant) wraps IOException from java.nio.file.Files.copy into FileSystemException 'Failed to copy <from> to <to>'. Vert.x throws it when a fileSystem().copy/copyBlocking call cannot complete at the OS level. The cause IOException details the precise reason (missing source, existing target, permissions).","triggerScenarios":"vertx.fileSystem().copy(from, to) or copyBlocking where resolveFile(from) doesn't exist, the target parent doesn't exist, the target exists without REPLACE_EXISTING, or the process lacks read/write permissions on either path.","commonSituations":"Typo in source path; target directory not created beforehand; copy over an existing file without CopyOption REPLACE_EXISTING; copying across filesystems without proper options; relative paths resolved against unexpected working directory in a fat jar.","solutions":["Check the cause message: 'NoSuchFileException' -> create the source/target parent dirs first; 'FileAlreadyExistsException' -> pass REPLACE_EXISTING or delete the target.","Verify permissions on both source and target with the user running the Vert.x process.","Confirm path resolution: use absolute paths or set the working directory explicitly, remembering fat-jar classpath resolution in FileResolver.","If you need recursive copy, use copy(from, to, true) — the non-recursive variant fails on directories."],"exampleFix":"// before\nvertx.fileSystem().copyBlocking(\"a.txt\", \"b.txt\"); // fails if b.txt exists\n// after\nvertx.fileSystem().copyBlocking(\"a.txt\", \"b.txt\",\n    java.nio.file.StandardCopyOption.REPLACE_EXISTING);","handlingStrategy":"validation","validationCode":"FileSystem fs = vertx.fileSystem();\nif (!fs.existsBlocking(from)) throw new FileNotFoundException(from);\nPath t = Paths.get(to);\nif (Files.exists(t) && !overwrite) throw new FileAlreadyExistsException(to);\nif (t.getParent() != null) Files.createDirectories(t.getParent());\nif (!Files.isReadable(Paths.get(from))) throw new AccessDeniedException(from);","typeGuard":"static boolean isCopyable(Path from, Path to, boolean overwrite) {\n  return Files.isRegularFile(from) && Files.isReadable(from)\n      && (overwrite || !Files.exists(to)) && Files.isDirectory(to.getParent());\n}","tryCatchPattern":"try {\n  fs.copyBlocking(from, to);\n} catch (FileSystemException e) {\n  if (e.getCause() instanceof FileAlreadyExistsException) {\n    fs.copyBlocking(from, to, StandardCopyOption.REPLACE_EXISTING);\n  } else throw e;\n}","preventionTips":["Create target parent directories before copying","Pass REPLACE_EXISTING when overwriting is intended","Use absolute paths to avoid fat-jar relative-path resolution surprises","Use copy(from, to, true) for directories"],"tags":["file-system","copy","io","nio"],"backgroundTag":"file-write-failed","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}