{"record":{"id":"5f8efae25ae18c52","repo":"apache/hadoop","slug":"move-destination-must-be-different-from-source-for","errorCode":null,"errorMessage":"Move destination must be different from source for %s.","messagePattern":"Move destination must be different from source for (.+?)\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorage.java","lineNumber":730,"sourceCode":"\n    for (Map.Entry<StorageResourceId, StorageResourceId> entry :\n        sourceToDestinationObjectsMap.entrySet()) {\n      StorageResourceId source = entry.getKey();\n      StorageResourceId destination = entry.getValue();\n      String srcBucketName = source.getBucketName();\n      String dstBucketName = destination.getBucketName();\n      // Avoid move across buckets.\n      if (!srcBucketName.equals(dstBucketName)) {\n        throw new UnsupportedOperationException(\n            \"This operation is not supported across two different buckets.\");\n      }\n      checkArgument(\n          !isNullOrEmpty(source.getObjectName()), \"srcObjectName must not be null or empty\");\n      checkArgument(\n          !isNullOrEmpty(destination.getObjectName()), \"dstObjectName must not be null or empty\");\n      if (srcBucketName.equals(dstBucketName)\n          && source.getObjectName().equals(destination.getObjectName())) {\n        throw new IllegalArgumentException(\n            String.format(\n                \"Move destination must be different from source for %s.\",\n                StringPaths.fromComponents(srcBucketName, source.getObjectName())));\n      }\n    }\n  }\n\n  void copy(Map<StorageResourceId, StorageResourceId> sourceToDestinationObjectsMap)\n      throws IOException {\n    validateCopyArguments(sourceToDestinationObjectsMap, this);\n\n    if (sourceToDestinationObjectsMap.isEmpty()) {\n      return;\n    }\n\n    for (Map.Entry<StorageResourceId, StorageResourceId> entry :\n        sourceToDestinationObjectsMap.entrySet()) {\n      StorageResourceId srcObject = entry.getKey();","sourceCodeStart":712,"sourceCodeEnd":748,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-cloud-storage-project/hadoop-gcp/src/main/java/org/apache/hadoop/fs/gs/GoogleCloudStorage.java#L712-L748","documentation":"During move validation, after the cross-bucket check, the code rejects pairs where source and destination are the same bucket AND the same object name, throwing IllegalArgumentException(\"Move destination must be different from source for %s.\"). A self-move is a no-op at best and a livelock at worst, so the API demands callers filter it themselves.","triggerScenarios":"Calling move/rename with src == dst (identical bucket and object name), e.g. fs.rename(path, path), or a bulk move map that includes identity entries — often produced by directory-rename code that maps a parent onto itself for root entries.","commonSituations":"Rename loops that compute destination by string replacement and produce the same path; task commit moving files into a directory they are already in; recursive directory moves that include the directory itself in the file list.","solutions":["Filter identity mappings before calling move: skip when src.equals(dst)","Fix the destination-path computation so renames actually change the object name","For fs.rename(path, path), short-circuit to success in calling code — it is a no-op"],"exampleFix":"// before\nfor (Map.Entry<StorageResourceId, StorageResourceId> e : moves.entrySet()) {\n  gcs.moveObjects(...); // may contain src==dst -> IllegalArgumentException\n}\n\n// after\nfor (Map.Entry<StorageResourceId, StorageResourceId> e : moves.entrySet()) {\n  if (!e.getKey().equals(e.getValue())) {\n    gcs.moveObjects(...);\n  }\n}","handlingStrategy":"validation","validationCode":"// Drop identity mappings before moving\nMap<StorageResourceId, StorageResourceId> moves = ...;\nmoves.entrySet().removeIf(e -> e.getKey().equals(e.getValue()));\ngcs.moveObjects(moves);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Skip src==dst pairs early — they are no-ops","Unit-test destination-path computation for rename helpers","Treat fs.rename(p, p) as success in wrappers"],"tags":["gcs","hadoop-gcp","rename","no-op","argument-validation"],"backgroundTag":"same-source-destination-move","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}