flowable/flowable-engine · error · FlowableObjectNotFoundException
Cannot find task with id
Error message
Cannot find task with id
What it means
CreateAttachmentCmd.verifyTaskParameters looks up the task by taskId via the task service; when no task exists with that id it throws FlowableObjectNotFoundException with the task class. This guards referential integrity of attachments: they must attach to a real task.
Solutions
- Fetch the task first (taskService.createTaskQuery().taskId(taskId).singleResult()) and only create the attachment if it is non-null.
- Correct the taskId source; ensure the id passed is the persistent task id (String) not a business key.
- Catch FlowableObjectNotFoundException and handle as a business 'task no longer exists' case if the task may legitimately disappear.
Example fix
// before
taskService.createAttachment(null, taskId, processInstanceId, name, description, url);
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
throw new IllegalArgumentException("Unknown taskId: " + taskId);
}
taskService.createAttachment(null, taskId, task.getProcessInstanceId(), name, description, url); Defensive patterns
Strategy: validation
Validate before calling
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
throw new IllegalArgumentException("Task does not exist: " + taskId);
} Try / catch
try {
taskService.createAttachment(null, taskId, pid, name, desc, url);
} catch (FlowableObjectNotFoundException e) {
log.warn("Task vanished before attachment: {}", taskId);
} Prevention
- Resolve and use Task objects returned by queries instead of cached raw ids
- Handle 'task completed/deleted' races in async workflows before writing attachments
- Keep attachment creation in the same transaction/session as the task interaction
When it happens
Trigger: Calling TaskService.createAttachment(...) with a taskId that does not match any task in the database (typo, already-deleted task, attachment created after the task/completed-and-removed task, wrong data source).
Common situations: Stale task ids held by a client after the task was completed and historic data cleaned; copy-pasted ids between test and prod databases; creating attachments in an async job after the task was deleted.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- A delegated cannot be completed, but should be resolved…
- Cannot add a comment to a suspended
- Cannot find task with id
- Cannot find task with id
- Cannot find task with id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/9cde2bbcc1c67aa8.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/CreateAttachmentCmd.java:143
processDefinitionId = process.getProcessDefinitionId();
}
}
eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_CREATED, attachment,
processInstanceId, processInstanceId, processDefinitionId), processEngineConfiguration.getEngineCfgKey());
eventDispatcher.dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_INITIALIZED, attachment,
processInstanceId, processInstanceId, processDefinitionId), processEngineConfiguration.getEngineCfgKey());
}
return attachment;
}
protected TaskEntity verifyTaskParameters(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskEntity task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
if (task == null) {
throw new FlowableObjectNotFoundException("Cannot find task with id " + taskId, Task.class);
}
if (task.isSuspended()) {
throw new FlowableException("It is not allowed to add an attachment to a suspended " + task);
}
return task;
}
protected ExecutionEntity verifyExecutionParameters(CommandContext commandContext) {
ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(processInstanceId);
if (execution == null) {
throw new FlowableObjectNotFoundException("Process instance " + processInstanceId + " doesn't exist", ProcessInstance.class);
}
if (execution.isSuspended()) {
throw new FlowableException("It is not allowed to add an attachment to a suspended " + execution);View on GitHub (pinned to d6d39ce1c6)