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

  1. Verify the taskId exists via taskService.createTaskQuery().taskId(id).singleResult() or HistoricTaskInstanceQuery before fetching the form model
  2. If the task may be completed, query the historic task and set historic=true in the form model options
  3. Check you are connected to the same database/schema/tenant where the task was created
  4. 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

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


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)