{"record":{"id":"e8e5d0aa89512712","repo":"apache/seatunnel","slug":"cannot-rename-s-under-itself-s","errorCode":null,"errorMessage":"Cannot rename %s under itself : %s","messagePattern":"Cannot rename (.+?) under itself : (.+?)","errorType":"exception","errorClass":"IOException","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":845,"sourceCode":"     * @throws IOException IOException\n     */\n    private boolean rename(FTPClient client, Path src, Path dst) throws IOException {\n        Path workDir = new Path(client.printWorkingDirectory());\n        Path absoluteSrc = makeAbsolute(workDir, src);\n        Path absoluteDst = makeAbsolute(workDir, dst);\n        if (!exists(client, absoluteSrc)) {\n            throw new FileNotFoundException(\"Source path \" + src + \" does not exist\");\n        }\n        if (isDirectory(absoluteDst)) {\n            // destination is a directory: rename goes underneath it with the\n            // source name\n            absoluteDst = new Path(absoluteDst, absoluteSrc.getName());\n        }\n        if (exists(client, absoluteDst)) {\n            throw new FileAlreadyExistsException(\"Destination path \" + dst + \" already exists\");\n        }\n        if (isParentOf(absoluteSrc, absoluteDst)) {\n            throw new IOException(\n                    \"Cannot rename \" + absoluteSrc + \" under itself\" + \" : \" + absoluteDst);\n        }\n        String from = absoluteSrc.toUri().getPath();\n        String to = absoluteDst.toUri().getPath();\n        return client.rename(from, to);\n    }\n\n    @Override\n    public Path getWorkingDirectory() {\n        // Return home directory always since we do not maintain state.\n        return getHomeDirectory();\n    }\n\n    @Override\n    public Path getHomeDirectory() {\n        FTPClient client = null;\n        try {\n            client = connect();","sourceCodeStart":827,"sourceCodeEnd":863,"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#L827-L863","documentation":"rename() guards against a degenerate move: if the destination path lies underneath the source path (isParentOf(absoluteSrc, absoluteDst)), moving a directory into itself is impossible, so it throws a plain IOException 'Cannot rename %s under itself : %s'.","triggerScenarios":"rename(client, src, dst) where absoluteDst is a subpath of absoluteSrc — e.g. renaming '/data' to '/data/archive/data' or renaming a dir to a path inside itself.","commonSituations":"Programmatic path construction bug where the output directory is computed from the input directory; misconfigured staging dir located inside the directory being renamed; recursive backup logic that nests the source under its own child.","solutions":["Fix the destination path computation so dst is not inside src","Move the source to a sibling/temp path first, then relocate it to the final nested location in two steps","Review config that derives the output path from the input path; add an assert src is not an ancestor of dst before calling rename"],"exampleFix":"// before\nfs.rename(new Path(\"/data\"), new Path(\"/data/archive/data\")); // invalid\n// after\nPath src = new Path(\"/data\");\nPath dst = new Path(\"/data-new\"); // sibling, not a descendant\nfs.rename(src, dst);","handlingStrategy":"validation","validationCode":"// Java: reject nested rename before calling the API\nPath src = new Path(\"/data\");\nPath dst = new Path(\"/data/archive\");\nif (dst.toString().startsWith(src.toString() + \"/\")) {\n    throw new IllegalArgumentException(\"Cannot rename \"+src+\" under itself\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    fs.rename(src, dst);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"under itself\")) {\n        logger.error(\"Path construction bug: dst is inside src\");\n    }\n}","preventionTips":["Assert dst is not a descendant of src before renaming","Avoid deriving output paths by concatenation onto the input directory","Use sibling temp directories for staging"],"tags":["ftp","rename","invalid-argument"],"backgroundTag":"invalid-argument-value","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"}