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

  1. Confirm the task exists: cmmnTaskService.createTaskQuery().taskId(id).singleResult() or cmmnHistoryService.createHistoricTaskInstanceQuery().taskId(id)
  2. Use the CMMN task service (not the BPMN one) for CMMN task ids
  3. If tasks were purged by history cleanup, the form model is no longer retrievable — fetch forms before cleanup or persist them separately
  4. 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

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


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)