flowable/flowable-engine · error · FlowableObjectNotFoundException
Task ' ' does not have an attachment with id ' '.
Error message
Task '{taskId}' does not have an attachment with id '{attachmentId}'. What it means
FlowableObjectNotFoundException thrown when reading a single task attachment: no attachment exists with the given id, or it belongs to a different task than the path parameter. Note it declares Comment.class as the entity class — a copy-paste artifact — but the semantics are attachment-not-found.
Solutions
- List the task's attachments (GET .../attachments) and use a returned id
- Confirm the taskId/attachmentId pair from the original creation response
- Point the client at the correct database/tenant
- Check the attachment was not deleted by another process
Example fix
// before
GET /runtime/tasks/101/attachments/wrong-id
// after
GET /runtime/tasks/101/attachments // then
GET /runtime/tasks/101/attachments/{id-from-list} Defensive patterns
Strategy: validation
Validate before calling
const list = await api.getTaskAttachments(taskId);
if (!list.some(a => a.id === attachmentId)) throw new Error('attachmentId not in task attachment list'); Try / catch
try { return await api.getTaskAttachment(taskId, attachmentId); } catch (e) { if (e.status === 404) return null; throw e; } Prevention
- Always derive attachmentId from the task's own attachment list
- Treat 404 as expected for stale ids and refresh the list
- Confirm environment/tenant before querying
When it happens
Trigger: GET /runtime/tasks/{taskId}/attachments/{attachmentId} where taskService.getAttachment(attachmentId) is null or the attachment's taskId differs from the path taskId.
Common situations: Attachment id from another task or process; attachment deleted earlier; wrong REST deployment/tenant pointing at another database; stale cached ids in client code.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Attachment with id ' ' does not have content associated…
- Task ' ' does not have an attachment with id ' '.
- Attachment content is required.
- Could not find a app model json with id
- Could not find a dead letter job with id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0b90d32a49bb666f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskAttachmentResource.java:55
* @author Frederik Heremans
*/
@RestController
@Api(tags = { "Task Attachments" }, authorizations = { @Authorization(value = "basicAuth") })
public class TaskAttachmentResource extends TaskBaseResource {
@ApiOperation(value = "Get an attachment on a task", tags = { "Task Attachments" })
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Indicates the task and attachment were found and the attachment is returned."),
@ApiResponse(code = 404, message = "Indicates the requested task was not found or the tasks does not have a attachment with the given ID.")
})
@GetMapping(value = "/runtime/tasks/{taskId}/attachments/{attachmentId}", produces = "application/json")
public AttachmentResponse getAttachment(@ApiParam(name = "taskId") @PathVariable("taskId") String taskId, @ApiParam(name = "attachmentId") @PathVariable("attachmentId") String attachmentId) {
HistoricTaskInstance task = getHistoricTaskFromRequest(taskId);
Attachment attachment = taskService.getAttachment(attachmentId);
if (attachment == null || !task.getId().equals(attachment.getTaskId())) {
throw new FlowableObjectNotFoundException("Task '" + task.getId() + "' does not have an attachment with id '" + attachmentId + "'.", Comment.class);
}
return restResponseFactory.createAttachmentResponse(attachment);
}
@ApiOperation(value = "Delete an attachment on a task", tags = { "Task Attachments"}, code = 204)
@ApiResponses(value = {
@ApiResponse(code = 204, message = "Indicates the task and attachment were found and the attachment is deleted. Response body is left empty intentionally."),
@ApiResponse(code = 404, message = "Indicates the requested task was not found or the tasks does not have a attachment with the given ID.")
})
@DeleteMapping(value = "/runtime/tasks/{taskId}/attachments/{attachmentId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteAttachment(@ApiParam(name = "taskId") @PathVariable("taskId") String taskId, @ApiParam(name = "attachmentId") @PathVariable("attachmentId") String attachmentId) {
Task task = getTaskFromRequestWithoutAccessCheck(taskId);
Attachment attachment = taskService.getAttachment(attachmentId);
if (attachment == null || !task.getId().equals(attachment.getTaskId())) {View on GitHub (pinned to d6d39ce1c6)