flowable/flowable-engine · error · FlowableObjectNotFoundException
Task not found with id
Error message
Task not found with id
What it means
FlowableObjectNotFoundException thrown by GetTaskFormModelCmd.execute when no task exists for the given taskId. The command looks up the task (runtime or historic depending on the 'historic' flag) and aborts before building the form model. It signals a caller-supplied identifier that does not reference any task in the engine database.
Solutions
- Verify the taskId exists via taskService.createTaskQuery().taskId(id).singleResult() or HistoricTaskInstanceQuery before fetching the form model
- If the task may be completed, query the historic task and set historic=true in the form model options
- Check you are connected to the same database/schema/tenant where the task was created
- Catch FlowableObjectNotFoundException and return a 404-style response instead of a 500
Example fix
// before
FormInfo form = taskService.getTaskFormModel(taskId); // throws if task gone
// after
Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
if (t == null) {
HistoricTaskInstance h = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
if (h == null) throw new NotFoundException("No task " + taskId);
}
FormInfo form = taskService.getTaskFormModel(taskId, true); Defensive patterns
Strategy: try-catch
Validate before calling
boolean exists = taskService.createTaskQuery().taskId(taskId).count() > 0
|| historyService.createHistoricTaskInstanceQuery().taskId(taskId).count() > 0; Try / catch
try {
FormInfo form = taskService.getTaskFormModel(taskId);
} catch (FlowableObjectNotFoundException e) {
respond(404, "Task or form not found: " + e.getMessage());
} Prevention
- Resolve task ids from engine queries, never from client-supplied stale state
- Prefer the historic=true form model variant when tasks may be completed
- Keep form definitions deployed together with the process definitions that reference them
When it happens
Trigger: Calling TaskService.getTaskFormModel(taskId) (or formService equivalents) with a taskId that is null-like-but-nonnull garbage, already completed-and-deleted, mistyped, or from a different engine/database when historic=false and no historic task exists either.
Common situations: REST/API callers caching stale task ids after task completion; querying with a historic task id while historic=false; multi-tenant setups where the id exists in another tenant's data; typos or id truncation when wiring ids through integration code.
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
- Cannot find task with id " + taskId
- 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/90a98981bb55a713.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetTaskFormModelCmd.java:74
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
FormService formService = CommandContextUtil.getFormService();
if (formService == null) {
throw new FlowableIllegalArgumentException("Form engine is not initialized");
}
TaskInfo task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
Date endTime = null;
if (task == null) {
historic = true;
task = processEngineConfiguration.getTaskServiceConfiguration().getHistoricTaskService().getHistoricTask(taskId);
if (task != null) {
endTime = ((HistoricTaskInstance) task).getEndTime();
}
}
if (task == null) {
throw new FlowableObjectNotFoundException("Task not found with id " + taskId);
}
Map<String, Object> variables = new HashMap<>();
if (!ignoreVariables && task.getProcessInstanceId() != null) {
if (!historic) {
processEngineConfiguration.getTaskService()
.getVariableInstances(taskId).values()
.stream()
.forEach(variableInstance -> variables.putIfAbsent(variableInstance.getName(), variableInstance.getValue()));
processEngineConfiguration.getRuntimeService().getVariableInstances(task.getProcessInstanceId()).values()
.stream()
.forEach(variableInstance -> variables.putIfAbsent(variableInstance.getName(), variableInstance.getValue()));
} else {
View on GitHub (pinned to d6d39ce1c6)