conductor-oss/conductor · warning · ConflictException
File already uploaded: {}
Error message
File already uploaded: {} What it means
Thrown by FileStorageServiceImpl.confirmUpload when the file's upload status is already UPLOADED. Confirming an already-completed upload is idempotent-rejected as a ConflictException (HTTP 409) to prevent double-completion or duplicate metadata updates.
Source
Thrown at core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java:102
public FileUploadUrlResponse getUploadUrl(String workflowId, String fileId) {
FileModel model = getOwnedFile(workflowId, fileId);
String uploadUrl =
fileStorage.generateUploadUrl(
model.getStoragePath(), properties.getSignedUrlExpiration());
long expiresAt = Instant.now().plus(properties.getSignedUrlExpiration()).toEpochMilli();
FileUploadUrlResponse response = new FileUploadUrlResponse();
response.setFileHandleId(FileIdToFileHandleIdConverter.toFileHandleId(fileId));
response.setUploadUrl(uploadUrl);
response.setExpiresAt(expiresAt);
return response;
}
@Override
public FileUploadCompleteResponse confirmUpload(String workflowId, String fileId) {
FileModel model = getOwnedFile(workflowId, fileId);
if (model.getUploadStatus() == FileUploadStatus.UPLOADED) {
throw new ConflictException("File already uploaded: " + fileId);
}
StorageFileInfo info = fileStorage.getStorageFileInfo(model.getStoragePath());
if (info == null || !info.isExists()) {
throw new NonTransientException("File not found on storage backend: " + fileId);
}
fileMetadataDAO.updateUploadComplete(
fileId, FileUploadStatus.UPLOADED, info.getContentHash(), info.getContentSize());
FileUploadCompleteResponse response = new FileUploadCompleteResponse();
response.setFileHandleId(FileIdToFileHandleIdConverter.toFileHandleId(fileId));
response.setUploadStatus(FileUploadStatus.UPLOADED);
response.setContentHash(info.getContentHash());
return response;
}
@OverrideView on GitHub (pinned to cf7c3e4a8a)
Solutions
- Treat a 409 'already uploaded' as success in the client (idempotent completion).
- Track confirm state client-side to avoid redundant confirm calls.
- Use the returned status to short-circuit subsequent retries.
Example fix
// before
fileStorageService.confirmUpload(wfId, fileId); // throws on second call
// after - treat 409 as already-complete
try {
fileStorageService.confirmUpload(wfId, fileId);
} catch (ConflictException e) {
// already uploaded; nothing to do
} Defensive patterns
Strategy: try-catch
Validate before calling
FileHandle meta = fileStorageService.getFileMetadata(wfId, fileId); boolean alreadyDone = meta.getUploadStatus() == FileUploadStatus.UPLOADED;
Try / catch
try {
fileStorageService.confirmUpload(wfId, fileId);
} catch (ConflictException e) {
// already uploaded; treat as success
} Prevention
- Make confirm idempotent on the client (409 = done)
- Avoid retrying confirm after success
When it happens
Trigger: Calling confirmUpload a second time for the same fileId; retrying confirmUpload after it already succeeded; client double-submitting the confirm request.
Common situations: At-least-once delivery with no idempotency guard on the client; frontend retry after a timeout where the first call actually succeeded; orchestrator replay of the confirm step.
Related errors
- File is not accepting content uploads: {}
- File not found on storage backend: {}
- File not yet uploaded: {}, status={}
- Skill {name} version {version} already exists with a differe
- conductor.file-storage.conductor.signing.keys is required wh
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/2eb71625dc333c4e.
Report an issue: GitHub.