{"record":{"id":"4b6b1a141cb49661","repo":"conductor-oss/conductor","slug":"workflow-does-not-own-file","errorCode":null,"errorMessage":"Workflow does not own file: {}","messagePattern":"Workflow does not own file: (.+?)","errorType":"exception","errorClass":"AccessForbiddenException","httpStatus":403,"severity":"error","filePath":"core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java","lineNumber":232,"sourceCode":"        response.setFileHandleId(FileIdToFileHandleIdConverter.toFileHandleId(fileId));\n        response.setUploadStatus(FileUploadStatus.UPLOADED);\n        response.setContentHash(info.getContentHash());\n        return response;\n    }\n\n    @Override\n    public void abortMultipartUpload(String workflowId, String fileId, String uploadId) {\n        FileModel model = getOwnedFile(workflowId, fileId);\n        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","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/core/src/main/java/org/conductoross/conductor/core/storage/FileStorageServiceImpl.java#L214-L250","documentation":"Thrown by getOwnedFile when the supplied workflowId is null/blank or does not equal the file record's owning workflowId. Upload-state mutations (confirmUpload, uploadContent, getUploadUrl, multipart ops) may only be performed by the workflow that created the file. Raised as AccessForbiddenException (HTTP 403).","triggerScenarios":"Calling confirmUpload/getUploadUrl/uploadContent/multipart endpoints with a workflowId different from the file's owner; passing a blank workflowId; cross-workflow access to another workflow's file for a write operation.","commonSituations":"Sub-workflow attempting a write on a parent-owned file; client passing a stale or wrong workflow id; cross-tenant access attempt; misrouting a request to the wrong file.","solutions":["Pass the exact workflowId that owns the file (the one used in createFile).","For family-wide read/download use getDownloadUrl/downloadContent (family-accessible), not the write endpoints.","If a child workflow must write, have the owner create the file and pass the handle down with its workflowId."],"exampleFix":"// before - using the parent workflowId for a file owned by the child\nfileStorageService.confirmUpload(parentWfId, fileId); // throws 403\n\n// after - use the owning workflowId\nfileStorageService.confirmUpload(ownerWorkflowId, fileId);","handlingStrategy":"validation","validationCode":"FileHandle meta = fileStorageService.getFileMetadata(wfId, fileId);\nboolean isOwner = wfId != null && !wfId.isBlank() && wfId.equals(meta.getWorkflowId());","typeGuard":null,"tryCatchPattern":"try {\n    fileStorageService.confirmUpload(ownerWfId, fileId);\n} catch (AccessForbiddenException e) {\n    // not the owner; cannot mutate\n}","preventionTips":["Pass the exact owning workflowId for write operations","Use family-accessible read endpoints for parent/child access"],"tags":["file-storage","authorization","ownership","forbidden","conductor","java"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}