flowable/flowable-engine · error · FlowableObjectNotFoundException
Task not found with id
Error message
Task not found with id ${taskId} What it means
GetTaskFormModelCmd throws FlowableObjectNotFoundException when no task (runtime or historic) exists for the given taskId. The command checks the runtime task and falls back to historic task lookup before throwing.
Solutions
- Confirm the task exists: cmmnTaskService.createTaskQuery().taskId(id).singleResult() or cmmnHistoryService.createHistoricTaskInstanceQuery().taskId(id)
- Use the CMMN task service (not the BPMN one) for CMMN task ids
- If tasks were purged by history cleanup, the form model is no longer retrievable — fetch forms before cleanup or persist them separately
- Check the taskId comes from the same database/tenant environment
Example fix
// before
FormInfo info = cmmnTaskService.getTaskFormModel(taskId); // throws if task absent
// after
Task t = cmmnTaskService.createTaskQuery().taskId(taskId).singleResult();
HistoricTaskInstance ht = t == null ? cmmnHistoryService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult() : null;
if (t != null || ht != null) {
FormInfo info = cmmnTaskService.getTaskFormModel(taskId);
} Defensive patterns
Strategy: validation
Validate before calling
Task t = cmmnTaskService.createTaskQuery().taskId(taskId).singleResult();
HistoricTaskInstance ht = (t == null) ? cmmnHistoryService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult() : null;
if (t == null && ht == null) {
throw new IllegalArgumentException("No such CMMN task: " + taskId);
} Type guard
boolean taskExists(String taskId) {
return taskId != null && (cmmnTaskService.createTaskQuery().taskId(taskId).count() > 0
|| cmmnHistoryService.createHistoricTaskInstanceQuery().taskId(taskId).count() > 0);
} Try / catch
try {
FormInfo info = cmmnTaskService.getTaskFormModel(taskId);
} catch (FlowableObjectNotFoundException e) {
// task absent (runtime and historic): return 404
} Prevention
- Use the CMMN task service for CMMN task ids, not the BPMN one
- Fetch form models before history cleanup purges tasks
- Null-check query results before dereferencing ids
When it happens
Trigger: Calling cmmnTaskService.getTaskFormModel(taskId) with an id that matches neither a running CMMN task nor a historic task — deleted, completed-and-purged, or simply wrong id.
Common situations: Passing a BPMN task id to the CMMN task service (different task tables); using an id after history cleanup removed the historic task; typos or stale references from another environment's database.
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
- task doesn't exist
- Cannot find case definition for id:
- Cannot find case definition with id
- Cannot find case definition with id
- Cannot find case instance for id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/58c81c61007c3534.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/GetTaskFormModelCmd.java:72
@Override
public FormInfo execute(CommandContext commandContext) {
FormService formService = CommandContextUtil.getFormService();
if (formService == null) {
throw new FlowableIllegalArgumentException("Form engine is not initialized");
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
TaskInfo task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
Date endTime = null;
if (task == null) {
task = cmmnEngineConfiguration.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.getScopeId() != null) {
List<HistoricVariableInstance> variableInstances = cmmnEngineConfiguration.getCmmnHistoryService()
.createHistoricVariableInstanceQuery()
.caseInstanceId(task.getScopeId())
.list();
for (HistoricVariableInstance historicVariableInstance : variableInstances) {
variables.put(historicVariableInstance.getVariableName(), historicVariableInstance.getValue());
}
}
String parentDeploymentId = null;
if (StringUtils.isNotEmpty(task.getScopeDefinitionId())) {
PlanItemDefinition itemDefinition = CaseDefinitionUtil.getCmmnModel(task.getScopeDefinitionId()).findPlanItemDefinition(task.getTaskDefinitionKey());
boolean sameDeployment = true;View on GitHub (pinned to d6d39ce1c6)