{"record":{"id":"8471f9587f5776cf","repo":"apache/seatunnel","slug":"can-t-make-directory-for-path-s-since-it-is-a-fil","errorCode":null,"errorMessage":"Can't make directory for path %s since it is a file.","messagePattern":"Can't make directory for path (.+?) since it is a file\\.","errorType":"exception","errorClass":"ParentNotDirectoryException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java","lineNumber":729,"sourceCode":"            return success;\n        } finally {\n            disconnect(client);\n        }\n    }\n\n    /**\n     * Convenience method, so that we don't open a new connection when using this method from within\n     * another method. Otherwise every API invocation incurs the overhead of opening/closing a TCP\n     * connection.\n     */\n    private boolean mkdirs(FTPClient client, Path file, FsPermission permission)\n            throws IOException {\n        Path workDir = new Path(client.printWorkingDirectory());\n        Path absolute = makeAbsolute(workDir, file);\n        // If directory already exists, return true\n        if (exists(client, absolute)) {\n            if (isFile(client, absolute)) {\n                throw new ParentNotDirectoryException(\n                        String.format(\n                                \"Can't make directory for path %s since it is a file.\", absolute));\n            }\n            return true;\n        }\n\n        // Create parent directories if they don't exist\n        Path parent = absolute.getParent();\n        if (parent != null && !exists(client, parent)) {\n            mkdirs(client, parent, FsPermission.getDirDefault());\n        }\n\n        // Create the directory\n        String pathName = absolute.getName();\n        String parentDir = parent != null ? parent.toUri().getPath() : \"/\";\n\n        // Change to parent directory\n        if (!client.changeWorkingDirectory(parentDir)) {","sourceCodeStart":711,"sourceCodeEnd":747,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java#L711-L747","documentation":"Thrown by SeaTunnelFTPFileSystem's internal mkdir path as a ParentNotDirectoryException: the path passed to mkdir already exists but is a regular file, so a directory of that name cannot be created there.","triggerScenarios":"Calling fs.mkdirs(path) (or a code path that auto-creates directories) where an existing file occupies the exact same path — e.g. a previous run wrote /data/part-0 as a file and config now uses /data/part-0 as a directory.","commonSituations":"Output path configuration colliding with an existing file from a prior run; missing trailing-slash conventions causing a directory path to equal a file path; reused bucket/directory layout changed between job versions.","solutions":["Choose a different directory path that does not collide with an existing file","Delete the conflicting file first if it is safe to remove","Verify the path with fs.getFileStatus(path).isFile()/isDirectory() before mkdirs","Align directory naming conventions (e.g. always append a directory name, never rely on slash handling)"],"exampleFix":"// before\nfs.mkdirs(new Path(\"/data/2026-09-10\")); // exists as a file\n// after\nPath dir = new Path(\"/data/2026-09-10\");\nif (fs.exists(dir) && fs.getFileStatus(dir).isFile()) {\n    fs.delete(dir, false); // remove conflicting file, then create dir\n}\nfs.mkdirs(dir);","handlingStrategy":"validation","validationCode":"Path dir = new Path(\"/data/2026-09-10\");\nif (fs.exists(dir) && fs.getFileStatus(dir).isFile()) {\n    throw new IllegalStateException(\"Path exists as a file: \" + dir);\n}","typeGuard":null,"tryCatchPattern":"try {\n    fs.mkdirs(dir);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"since it is a file\")) {\n        // pick a new path or delete the conflicting file deliberately\n    } else { throw e; }\n}","preventionTips":["Check exists()+isFile() before mkdirs on reused paths","Adopt a consistent layout where directories and files never share a path prefix collision","Delete or archive old run outputs before reusing directory names","Use unique run-id based directory names to avoid collisions"],"tags":["ftp","mkdir","path-collision","directory"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}