{"record":{"id":"ed333fb371a36058","repo":"conductor-oss/conductor","slug":"file-has-no-workflowid","errorCode":null,"errorMessage":"File has no workflowId: {}","messagePattern":"File has no workflowId: (.+?)","errorType":"exception","errorClass":"AccessForbiddenException","httpStatus":403,"severity":"error","filePath":"core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java","lineNumber":241,"sourceCode":"        fileStorage.abortMultipartUpload(model.getStoragePath(), uploadId);\n    }\n\n    /** Upload state may only be mutated by the workflow that created the file record. */\n    private @NonNull FileModel getOwnedFile(String workflowId, String fileId) {\n        FileModel model = getFileModelOrThrow(fileId);\n        if (workflowId == null\n                || workflowId.isBlank()\n                || !workflowId.equals(model.getWorkflowId())) {\n            throw new AccessForbiddenException(\"Workflow does not own file: \" + fileId);\n        }\n        return model;\n    }\n\n    /** Downloads and metadata are visible to the owning workflow's full workflow family. */\n    private @NonNull FileModel getFamilyAccessibleFile(String workflowId, String fileId) {\n        FileModel model = getFileModelOrThrow(fileId);\n        if (model.getWorkflowId() == null || model.getWorkflowId().isBlank()) {\n            throw new AccessForbiddenException(\"File has no workflowId: \" + fileId);\n        }\n\n        Set<String> family = workflowFamilyResolver.getFamily(workflowId);\n        if (!family.contains(model.getWorkflowId())) {\n            throw new AccessForbiddenException(\"Workflow cannot access file: \" + fileId);\n        }\n        return model;\n    }\n\n    private FileModel getFileModelOrThrow(String fileId) {\n        FileModel model = fileMetadataDAO.getFileMetadata(fileId);\n        if (model == null) {\n            throw new NotFoundException(\"File not found: \" + fileId);\n        }\n        return model;\n    }\n}\n","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java#L223-L259","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before - record has null workflowId; any download attempt throws\nfileStorageService.getDownloadUrl(wfId, fileId); // 403\n\n// after - repair the metadata or recreate the file\nfileMetadataDAO.updateWorkflowId(fileId, ownerWorkflowId);\nfileStorageService.getDownloadUrl(ownerWorkflowId, fileId);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    fileStorageService.getDownloadUrl(wfId, fileId);\n} catch (AccessForbiddenException e) {\n    // file record has no workflowId (data integrity issue); repair or recreate\n}","preventionTips":["Audit file metadata records for null workflowId","Ensure createFile always persists workflowId","Treat this as a data corruption signal, not a caller error"],"tags":["file-storage","data-integrity","authorization","forbidden","conductor","java"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}