flowable/flowable-engine · error · ActivitiException

Task form definition for '' not found

Error message

Task form definition for '' not found

What it means

Thrown when the task exists but its task definition is null, meaning the task was not created from a parsed BPMN task definition (task.getTaskDefinition() == null), so no task form handler/definition is available.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/GetRenderedTaskFormCmd.java:52

    protected String taskId;
    protected String formEngineName;

    public GetRenderedTaskFormCmd(String taskId, String formEngineName) {
        this.taskId = taskId;
        this.formEngineName = formEngineName;
    }

    @Override
    public Object execute(CommandContext commandContext) {
        TaskEntity task = commandContext
                .getTaskEntityManager()
                .findTaskById(taskId);
        if (task == null) {
            throw new ActivitiObjectNotFoundException("Task '" + taskId + "' not found", Task.class);
        }

        if (task.getTaskDefinition() == null) {
            throw new ActivitiException("Task form definition for '" + taskId + "' not found");
        }

        TaskFormHandler taskFormHandler = task.getTaskDefinition().getTaskFormHandler();
        if (taskFormHandler == null) {
            return null;
        }

        FormEngine formEngine = commandContext
                .getProcessEngineConfiguration()
                .getFormEngines()
                .get(formEngineName);

        if (formEngine == null) {
            throw new ActivitiException("No formEngine '" + formEngineName + "' defined process engine configuration");
        }

        TaskFormData taskForm = taskFormHandler.createTaskForm(task);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Only request rendered forms for tasks created by a process execution (bound to a BPMN user task element).
  2. For ad-hoc tasks, skip form rendering and present a generic UI.
  3. Check the BPMN XML defines the user task properly so the TaskDefinition is populated at parse time.
  4. Verify the deployment containing the user task is the one that started the process instance.

Example fix

// before
taskService.getRenderedTaskForm(adHocTask.getId()); // task has no definition
// after
if (task.getProcessDefinitionId() != null) {
    taskService.getRenderedTaskForm(task.getId());
} else {
    // render a default form for standalone tasks
}
Defensive patterns

Strategy: type-guard

Validate before calling

Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
boolean hasDefinition = task != null && task.getProcessDefinitionId() != null;

Type guard

boolean isProcessBoundTask(Task task) {
    return task != null && task.getProcessDefinitionId() != null;
}

Try / catch

try {
    taskService.getRenderedTaskForm(taskId);
} catch (ActivitiException e) {
    if (e.getMessage().startsWith("Task form definition for")) {
        // render generic form for ad-hoc task
    }
}

Prevention

When it happens

Trigger: Rendering a form for a task whose TaskEntity was created without a TaskDefinition — e.g. standalone/ad-hoc tasks created via TaskService.newTask() that are not bound to a BPMN element with form metadata.

Common situations: Creating tasks programmatically with taskService.newTask() and then attempting to render their forms; process definitions where the target task element lacks form definition data; data migrated between engine versions leaving tasks without definitions.

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/edc993711324a2fb. Report an issue: GitHub.