{"record":{"id":"b6ecb2913720a25b","repo":"apache/hadoop","slug":"file-exists-b6ecb2","errorCode":null,"errorMessage":"File exists","messagePattern":"File exists","errorType":"exception","errorClass":"PathExistsException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/MoveCommands.java","lineNumber":65,"sourceCode":"        \"[-f] [-p] [-l] [-d] <localsrc> ... <dst>\";\n    public static final String DESCRIPTION = \n        \"Same as -put, except that the source is \" +\n        \"deleted after it's copied\\n\" +\n        \"and -t option has not yet implemented.\";\n\n    @Override\n    protected void processOptions(LinkedList<String> args) throws IOException {\n      if(args.contains(\"-t\")) {\n        throw new CommandFormat.UnknownOptionException(\"-t\");\n      }\n      super.processOptions(args);\n    }\n\n    @Override\n    protected void processPath(PathData src, PathData target) throws IOException {\n      // unlike copy, don't merge existing dirs during move\n      if (target.exists && target.stat.isDirectory()) {\n        throw new PathExistsException(target.toString());\n      }\n      super.processPath(src, target);\n    }\n    \n    @Override\n    protected void postProcessPath(PathData src) throws IOException {\n      if (!src.fs.delete(src.path, false)) {\n        // we have no way to know the actual error...\n        PathIOException e = new PathIOException(src.toString());\n        e.setOperation(\"remove\");\n        throw e;\n      }\n    }\n  }\n\n  /**\n   *  Move remote files to a local filesystem\n   */","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/shell/MoveCommands.java#L47-L83","documentation":"MoveFromLocal.processPath (MoveCommands.java:65) throws PathExistsException ('File exists' is its default message) when the destination exists and is a directory. Unlike copy (put), moveFromLocal does not merge sources into an existing destination directory — the comment reads 'unlike copy, don't merge existing dirs during move'.","triggerScenarios":"Running 'hadoop fs -moveFromLocal localsrc /existing/dir' where /existing/dir already exists as a directory. Passing a destination that a previous run of the same script already created.","commonSituations":"Re-running an idempotent upload script whose second run finds the destination directory created by the first; operators assuming -moveFromLocal behaves like -put (which merges into existing dirs); destination directories pre-created by provisioning tooling.","solutions":["Target a full destination file path instead of the directory: 'hadoop fs -moveFromLocal localsrc /existing/dir/newname'","Delete or rename the existing destination directory first if a fresh move is intended","Switch to 'hadoop fs -put localsrc /existing/dir' (merges) and delete the local source afterwards"],"exampleFix":"# before\nhadoop fs -moveFromLocal app.log /data/logs   # /data/logs exists -> File exists\n\n# after\nhadoop fs -moveFromLocal app.log /data/logs/app.log","handlingStrategy":"validation","validationCode":"# resolve a concrete destination file path before moving\nDEST_DIR=/data/logs\nDEST=\"$DEST_DIR/$(basename \"$LOCAL_SRC\")\"\nhadoop fs -test -d \"$DEST_DIR\" && hadoop fs -moveFromLocal \"$LOCAL_SRC\" \"$DEST\"","typeGuard":null,"tryCatchPattern":"catch (PathExistsException e) { pick a unique destination name (suffix timestamp/UUID) or delete the existing target, then retry }","preventionTips":["Always give moveFromLocal a full destination file path, not a bare directory","Make upload scripts idempotent with unique names or explicit cleanup"],"tags":["movefromlocal","file-exists","destination-conflict","hadoop-shell"],"backgroundTag":"destination-already-exists","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}