conductor-oss/conductor · error · AccessForbiddenException
File has no workflowId: {}
Error message
File has no workflowId: {} What it means
Thrown by getFamilyAccessibleFile when the file record's workflowId is null or blank. Family-based read access cannot be resolved without an owning workflow in the record, so the request is denied. Raised as AccessForbiddenException (HTTP 403). This indicates corrupted/incomplete file metadata rather than a caller mistake.
Source
Thrown at core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java:241
fileStorage.abortMultipartUpload(model.getStoragePath(), uploadId);
}
/** Upload state may only be mutated by the workflow that created the file record. */
private @NonNull FileModel getOwnedFile(String workflowId, String fileId) {
FileModel model = getFileModelOrThrow(fileId);
if (workflowId == null
|| workflowId.isBlank()
|| !workflowId.equals(model.getWorkflowId())) {
throw new AccessForbiddenException("Workflow does not own file: " + fileId);
}
return model;
}
/** Downloads and metadata are visible to the owning workflow's full workflow family. */
private @NonNull FileModel getFamilyAccessibleFile(String workflowId, String fileId) {
FileModel model = getFileModelOrThrow(fileId);
if (model.getWorkflowId() == null || model.getWorkflowId().isBlank()) {
throw new AccessForbiddenException("File has no workflowId: " + fileId);
}
Set<String> family = workflowFamilyResolver.getFamily(workflowId);
if (!family.contains(model.getWorkflowId())) {
throw new AccessForbiddenException("Workflow cannot access file: " + fileId);
}
return model;
}
private FileModel getFileModelOrThrow(String fileId) {
FileModel model = fileMetadataDAO.getFileMetadata(fileId);
if (model == null) {
throw new NotFoundException("File not found: " + fileId);
}
return model;
}
}
View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Inspect the file metadata record directly to confirm its workflowId field.
- Repair the record by setting the correct workflowId, or recreate the file under a valid workflow.
- If systemic, audit the createFile path to ensure workflowId is always persisted (note: createFile already rejects blank workflowId, so a null here implies data corruption/migration).
Example fix
// before - record has null workflowId; any download attempt throws fileStorageService.getDownloadUrl(wfId, fileId); // 403 // after - repair the metadata or recreate the file fileMetadataDAO.updateWorkflowId(fileId, ownerWorkflowId); fileStorageService.getDownloadUrl(ownerWorkflowId, fileId);
Defensive patterns
Strategy: try-catch
Try / catch
try {
fileStorageService.getDownloadUrl(wfId, fileId);
} catch (AccessForbiddenException e) {
// file record has no workflowId (data integrity issue); repair or recreate
} Prevention
- Audit file metadata records for null workflowId
- Ensure createFile always persists workflowId
- Treat this as a data corruption signal, not a caller error
When it happens
Trigger: Calling getDownloadUrl, downloadContent, or getFileMetadata for a file whose stored workflowId is empty (data integrity problem). The resolver cannot compute a workflow family from a missing owner.
Common situations: A legacy/migrated file record without workflowId; a bug created a file metadata row with a null workflowId; the DAO returned a partially-populated model.
Related errors
- Workflow does not own file: {}
- Workflow cannot access file: {}
- conductor.file-storage.conductor.signing.keys is required wh
- Each conductor.file-storage.conductor.signing.keys entry req
- conductor.file-storage.conductor.signing.keys contains dupli
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/ed333fb371a36058.
Report an issue: GitHub.