{"record":{"id":"e8acbe6097cf69d0","repo":"apache/dolphinscheduler","slug":"file-dstpath-already-exists-e8acbe","errorCode":null,"errorMessage":"file: ${dstPath} already exists","messagePattern":"file: (.+?) already exists","errorType":"exception","errorClass":"FileAlreadyExistsException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java","lineNumber":162,"sourceCode":"        BlobId target = BlobId.of(bucketName, dstPath);\n\n        gcsStorage.copy(\n                Storage.CopyRequest.newBuilder()\n                        .setSource(source)\n                        .setTarget(target)\n                        .build());\n\n        if (deleteSource) {\n            gcsStorage.delete(source);\n        }\n    }\n\n    @SneakyThrows\n    @Override\n    public void upload(String srcFile, String dstPath, boolean deleteSource, boolean overwrite) {\n        dstPath = transformAbsolutePathToGcsKey(dstPath);\n        if (exists(dstPath) && !overwrite) {\n            throw new FileAlreadyExistsException(\"file: \" + dstPath + \" already exists\");\n        }\n        BlobInfo blobInfo = BlobInfo.newBuilder(\n                BlobId.of(bucketName, dstPath)).build();\n\n        Path srcPath = Paths.get(srcFile);\n        gcsStorage.create(blobInfo, Files.readAllBytes(srcPath));\n\n        if (deleteSource) {\n            Files.delete(srcPath);\n        }\n    }\n\n    @SneakyThrows\n    @Override\n    public List<String> fetchFileContent(String filePath, int skipLineNums, int limit) {\n        filePath = transformAbsolutePathToGcsKey(filePath);\n        if (StringUtils.isBlank(filePath)) {\n            log.error(\"file path:{} is blank\", filePath);","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-storage-plugin/dolphinscheduler-storage-gcs/src/main/java/org/apache/dolphinscheduler/plugin/storage/gcs/GcsStorageOperator.java#L144-L180","documentation":"GcsStorageOperator.upload throws FileAlreadyExistsException when the destination GCS key already exists and overwrite=false. The exists() check precedes the blob create call. With overwrite=true the blob is simply recreated with the new content.","triggerScenarios":"Calling upload(srcFile, dstPath, deleteSource, false) when a blob exists at the transformed dstPath key.","commonSituations":"Re-uploading a resource with overwrite disabled; concurrent uploads of the same resource key; retry after partial workflow failure leaving the blob in place.","solutions":["Pass overwrite=true to replace the blob","Delete the existing blob first if it is safe","Upload to a new/unique key to keep the old object"],"exampleFix":"// before\ngcs.upload(localFile, resourceKey, false, false);\n// after\ngcs.upload(localFile, resourceKey, false, true);","handlingStrategy":"try-catch","validationCode":"if (!overwrite && gcs.exists(dstKey)) { /* rename dst or confirm overwrite */ }","typeGuard":null,"tryCatchPattern":"try {\n    gcs.upload(src, dst, deleteSource, overwrite);\n} catch (FileAlreadyExistsException e) {\n    gcs.upload(src, dst, deleteSource, true);\n}","preventionTips":["Set overwrite=true intentionally when replacement is expected","Use object versioning on the bucket to preserve replaced blobs","Avoid concurrent uploads of the same resource key"],"tags":["storage","gcs","duplicate-resource"],"backgroundTag":"file-already-exists","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}