flowable/flowable-engine · error · FlowableObjectNotFoundException
Cannot find task with id " + taskId
Error message
Cannot find task with id " + taskId
What it means
NeedsActiveTaskCmd looks the task up via the TaskService and throws FlowableObjectNotFoundException when no ACT_RU_TASK row matches the given taskId. The task either never existed or has already been completed/deleted and moved to history.
Solutions
- Before acting, check the task still exists: taskService.createTaskQuery().taskId(id).singleResult(), and handle null.
- If the task may be completed already, treat FlowableObjectNotFoundException as an idempotent no-op for 'complete' flows.
- Fetch fresh task ids from taskService.createTaskQuery() instead of reusing cached ids across sessions.
- Confirm the client and server point at the same Flowable schema/environment.
Example fix
// before
taskService.complete(taskId);
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task != null) {
taskService.complete(taskId);
} Defensive patterns
Strategy: validation
Validate before calling
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) { throw new NotFoundException("Task " + taskId + " not found or already completed"); } Type guard
boolean taskExists(String taskId) {
return taskId != null && taskService.createTaskQuery().taskId(taskId).count() > 0;
} Try / catch
try {
taskService.complete(taskId);
} catch (FlowableObjectNotFoundException e) {
log.info("Task {} already completed/removed; treating as no-op", taskId);
} Prevention
- Design complete/claim flows to be idempotent for already-finished tasks.
- Refresh task lists from TaskQuery instead of long-lived caches.
- Disable duplicate form submissions (disable button + idempotency key).
- Distinguish runtime vs history ids in your APIs.
When it happens
Trigger: Calling TaskService.claim/complete/resolve/setAssignee with a taskId that has no active task row, or operating on a task after another thread/user completed it.
Common situations: Double-submission of a task form (second complete finds nothing); stale UI holding a task id after completion; task id from history (ACT_HI_TASKINST) used against the runtime service; wrong database/environment.
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
- task " + taskId + " doesn't exist
- Cannot find task with id " + taskId
- Could not find a task instance with id
- Could not find task entity for id
- task
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/bd9aec60d5f420cd.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/NeedsActiveTaskCmd.java:53
protected String taskId;
public NeedsActiveTaskCmd(String taskId) {
this.taskId = taskId;
}
@Override
public T execute(CommandContext commandContext) {
if (taskId == null) {
throw new FlowableIllegalArgumentException("taskId is null");
}
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.isDeleted()) {
throw new FlowableException(task + " is already deleted");
}
if (task.isSuspended()) {
throw new FlowableException(getSuspendedTaskExceptionPrefix() + " a suspended " + task);
}
return execute(commandContext, task);
}
/**
* Subclasses must implement in this method their normal command logic. The provided task is ensured to be active.
*/
protected abstract T execute(CommandContext commandContext, TaskEntity task);
View on GitHub (pinned to d6d39ce1c6)