flowable/flowable-engine · error · FlowableObjectNotFoundException

Task '

Error message

Task '

What it means

FlowableObjectNotFoundException thrown by GetRenderedTaskFormCmd.execute when no task exists for the given taskId. The task service lookup returns null, so the command reports "Task '<id>' not found" with Task.class as the resource type. This differs from the null-id error: a real id was supplied but it does not match any persisted task.

Solutions

  1. Check task existence first with taskService.createTaskQuery().taskId(id).singleResult() and handle null in the UI.
  2. Reload the task list after task completion to avoid stale ids in the session/UI.
  3. Verify database and tenant configuration of the engine instance.
  4. Catch FlowableObjectNotFoundException around the call and show a 'task no longer available' message instead of a stack trace.

Example fix

// before
Object form = formService.getRenderedTaskForm(taskId); // may throw if stale
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
    return formUnavailable();
}
Object form = formService.getRenderedTaskForm(taskId);
Defensive patterns

Strategy: try-catch

Validate before calling

Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) { /* task gone: completed, deleted, or wrong db/tenant */ return null; }

Try / catch

try {
    return formService.getRenderedTaskForm(taskId);
} catch (FlowableObjectNotFoundException e) {
    // refresh the user's task list; treat as 404
}

Prevention

When it happens

Trigger: Calling formService.getRenderedTaskForm(taskId) with an id that is not in the task tables — already completed/deleted task, wrong database, id from a different engine instance, or a fabricated/garbage id.

Common situations: User renders a form for a task that was completed by someone else meanwhile (race condition); stale task ids cached in a web session; multi-tenant setup querying the wrong tenant; standalone app pointing at a different database than the workflow engine.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/331f444f10f4ba92. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetRenderedTaskFormCmd.java:57

    protected String taskId;
    protected String formEngineName;

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

    @Override
    public Object execute(CommandContext commandContext) {

        if (taskId == null) {
            throw new FlowableIllegalArgumentException("Task id should not be null");
        }

        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        TaskEntity task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
        if (task == null) {
            throw new FlowableObjectNotFoundException("Task '" + taskId + "' not found", Task.class);
        }

        FormHandlerHelper formHandlerHelper = processEngineConfiguration.getFormHandlerHelper();
        TaskFormHandler taskFormHandler = formHandlerHelper.getTaskFormHandlder(task);
        if (taskFormHandler != null) {

            FormEngine formEngine = processEngineConfiguration.getFormEngines().get(formEngineName);

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

            TaskFormData taskForm = taskFormHandler.createTaskForm(task);

            return formEngine.renderTaskForm(taskForm);
        }

        return null;

View on GitHub (pinned to d6d39ce1c6)