flowable/flowable-engine · error · ActivitiObjectNotFoundException
Cannot find task with id " + taskId
Error message
Cannot find task with id " + taskId
What it means
Thrown when the taskId is non-null but no task entity with that id exists; ActivitiObjectNotFoundException is raised with the expected Task.class. The task may have been completed or deleted, or the id belongs to a different engine/database.
Solutions
- Check existence first via taskService.createTaskQuery().taskId(id).singleResult() and handle the not-found case gracefully in the UI.
- Treat the task as already processed on ObjectNotFoundException (idempotent handling) rather than retrying blindly.
- Verify engine/datasource configuration so the call hits the database that actually owns the task.
- Refresh the task list instead of reusing cached ids from an old page render.
Example fix
// before
taskService.complete(taskId);
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task != null) {
taskService.complete(taskId);
} else {
logger.info("Task {} already completed or deleted", taskId);
} Defensive patterns
Strategy: validation
Validate before calling
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) throw new IllegalStateException("task not found: " + taskId); Try / catch
try {
taskService.complete(taskId);
} catch (ActivitiObjectNotFoundException e) {
// idempotent: task already completed or deleted
} Prevention
- Handle double-submits idempotently instead of treating not-found as fatal
- Refresh task lists in UIs instead of reusing stale ids
- Verify all nodes point at the same engine database
When it happens
Trigger: Calling taskService.complete/claim/setAssignee/etc. with an id of a task that was already completed, deleted by another user, never existed in this database, or comes from a stale form/UI payload.
Common situations: Double-submit: two users or retries complete the same task and the second call fails; long-lived UI sessions holding task ids after a DB cleanup; connecting to the wrong datasource or cluster.
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
- execution " + executionId + " doesn't exist
- Candidate group is null
- Candidate group list is empty
- Candidate group list is empty
- Candidate group list is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/92c1252d35c0f3b6.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/NeedsActiveTaskCmd.java:52
protected String taskId;
public NeedsActiveTaskCmd(String taskId) {
this.taskId = taskId;
}
@Override
public T execute(CommandContext commandContext) {
if (taskId == null) {
throw new ActivitiIllegalArgumentException("taskId is null");
}
TaskEntity task = commandContext
.getTaskEntityManager()
.findTaskById(taskId);
if (task == null) {
throw new ActivitiObjectNotFoundException("Cannot find task with id " + taskId, Task.class);
}
if (task.isSuspended()) {
throw new ActivitiException(getSuspendedTaskException());
}
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);
/**
* Subclasses can override this method to provide a customized exception message that will be thrown when the task is suspended.
*/
protected String getSuspendedTaskException() {View on GitHub (pinned to d6d39ce1c6)