{"record":{"id":"79fef25f015e64a7","repo":"apache/beam","slug":"target-object-already-exists-and-strategy-is-fail-if-exists","errorCode":null,"errorMessage":"Target object already exists and strategy is FAIL_IF_EXISTS","messagePattern":"Target object already exists and strategy is FAIL_IF_EXISTS","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV2.java","lineNumber":385,"sourceCode":"        } catch (StorageException e) {\n          throw translateStorageException(dstPath, e);\n        }\n\n        if (existingTarget == null) {\n          copyRequestBuilder.setTarget(dstId, Storage.BlobTargetOption.doesNotExist());\n        } else {\n          switch (dstOverwrite) {\n            case SKIP_IF_EXISTS:\n              LOG.warn(\"Ignoring rewriting from {} to {} because target exists.\", srcPath, dstPath);\n              continue; // Skip to next file in for-loop\n\n            case SAFE_OVERWRITE:\n              copyRequestBuilder.setTarget(\n                  dstId, Storage.BlobTargetOption.generationMatch(existingTarget.getGeneration()));\n              break;\n\n            case FAIL_IF_EXISTS:\n              throw new FileAlreadyExistsException(\n                  srcPath.toString(),\n                  dstPath.toString(),\n                  \"Target object already exists and strategy is FAIL_IF_EXISTS\");\n            default:\n              throw new IllegalStateException(\"Unknown OverwriteStrategy: \" + dstOverwrite);\n          }\n        }\n      }\n\n      try {\n        CopyWriter copyWriter = storage.copy(copyRequestBuilder.build());\n        copyWriter.getResult();\n\n        if (deleteSrc) {\n          if (!storage.delete(srcId)) {\n            // This may happen if the source file is deleted by another process after copy.\n            LOG.warn(\n                \"Source file {} could not be deleted after move to {}. It may not have existed.\",","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV2.java#L367-L403","documentation":"In GcsUtilV2.rewriteHelper (used by copy and move), when the destination object already exists and the OverwriteStrategy is FAIL_IF_EXISTS, a FileAlreadyExistsException is thrown naming source, destination, and the reason. It is the strict, no-clobber copy mode.","triggerScenarios":"Calling copy/move with OverwriteStrategy.FAIL_IF_EXISTS (e.g. Beam CreateOptions with StandardCreateOptions.IGNORE_EXISTING_FILES semantics inverted, or explicit FAIL_IF_EXISTS) where the destination object's generation already exists.","commonSituations":"Re-running a job that copies outputs to a versionless destination path; two concurrent jobs writing the same destination filename; migrating data into a bucket that already contains the target objects.","solutions":["Switch to OverwriteStrategy.SAFE_OVERWRITE (generationMatch) or OVERWRITE if clobbering is acceptable.","Include a unique run ID/timestamp in destination paths so re-runs don't collide.","Pre-check destination existence and skip or rename before copying.","Catch FileAlreadyExistsException and treat as skip for idempotent pipelines."],"exampleFix":"// before\ngcsUtil.copy(src, dst, CreateOptions.withOverwrite(OverwriteStrategy.FAIL_IF_EXISTS));\n// after: unique per-run destination\nGcsPath dst = GcsPath.fromUri(String.format(\"gs://bucket/out/%s/\", runId));","handlingStrategy":"try-catch","validationCode":"// pre-check destination\nif (gcsUtil.getBlob(dstPath, Storage.BlobGetOption.fields()) != null) {\n  // destination exists: pick new path or choose an overwrite strategy\n}","typeGuard":null,"tryCatchPattern":"try {\n  gcsUtil.copy(src, dst, FAIL_IF_EXISTS_options);\n} catch (FileAlreadyExistsException e) {\n  // skip (idempotent re-run) or retry with a unique destination\n}","preventionTips":["Embed unique run IDs in destination paths","Choose SAFE_OVERWRITE/OVERWRITE deliberately instead of FAIL_IF_EXISTS when clobbering is fine","Pre-check destinations before bulk copies"],"tags":["gcs","file-already-exists","copy","java","apache-beam"],"backgroundTag":"file-already-exists","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}