{"record":{"id":"bddccff0a2463149","repo":"conductor-oss/conductor","slug":"workflow-cannot-access-file","errorCode":null,"errorMessage":"Workflow cannot access file: {}","messagePattern":"Workflow cannot access file: (.+?)","errorType":"exception","errorClass":"AccessForbiddenException","httpStatus":403,"severity":"error","filePath":"core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java","lineNumber":246,"sourceCode":"        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":228,"sourceCodeEnd":259,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java#L228-L259","documentation":"Thrown by getFamilyAccessibleFile when the caller's workflowId is not part of the workflow family that owns the file. Downloads and metadata reads are visible to the full workflow family (parent + sub-workflows), but a workflow outside that family is denied. Raised as AccessForbiddenException (HTTP 403).","triggerScenarios":"Calling getDownloadUrl/downloadContent/getFileMetadata with a workflowId whose resolved family (via WorkflowFamilyResolver) does not contain the file's owning workflowId. E.g. an unrelated workflow trying to read another workflow's file.","commonSituations":"Caller passing the wrong workflowId; sibling (non-parent/child) workflow attempting access; the family resolver does not recognize the relationship (e.g. dynamic fork not tracked); cross-tenant access.","solutions":["Use the workflowId of the file owner or a workflow that is a parent/child of the owner.","If a legitimate family relationship is missing, verify WorkflowFamilyResolver registers the parent/sub-workflow link.","Route the read through the owning workflow if family access is not intended."],"exampleFix":"// before - unrelated workflow id\nfileStorageService.getDownloadUrl(unrelatedWfId, fileId); // 403\n\n// after - use a workflow in the owning family\nfileStorageService.getDownloadUrl(ownerOrParentWfId, fileId);","handlingStrategy":"validation","validationCode":"Set<String> family = workflowFamilyResolver.getFamily(wfId);\nFileHandle meta = fileStorageService.getFileMetadata(wfId, fileId);\nboolean accessible = family.contains(meta.getWorkflowId());","typeGuard":null,"tryCatchPattern":"try {\n    fileStorageService.getDownloadUrl(wfId, fileId);\n} catch (AccessForbiddenException e) {\n    // caller not in file's workflow family\n}","preventionTips":["Use the owner or a parent/child workflow id for reads","Verify WorkflowFamilyResolver tracks parent/sub-workflow links"],"tags":["file-storage","authorization","family-access","forbidden","conductor","java"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}