flowable/flowable-engine · error · FlowableObjectNotFoundException

task ${taskId} doesn't exist

Error message

task ${taskId} doesn't exist

What it means

GetTaskVariableInstancesCmd fetches the task entity before reading its variable instances. When the task service returns no task for the given taskId, the command throws FlowableObjectNotFoundException('task <id> doesn't exist', Task.class): the id is well-formed but references a task that no longer exists.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/GetTaskVariableInstancesCmd.java:54

    protected boolean isLocal;

    public GetTaskVariableInstancesCmd(String taskId, Collection<String> variableNames, boolean isLocal) {
        this.taskId = taskId;
        this.variableNames = variableNames;
        this.isLocal = isLocal;
    }

    @Override
    public Map<String, VariableInstance> execute(CommandContext commandContext) {
        if (taskId == null) {
            throw new FlowableIllegalArgumentException("taskId is null");
        }

        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        TaskEntity task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);

        if (task == null) {
            throw new FlowableObjectNotFoundException("task " + taskId + " doesn't exist", Task.class);
        }

        Map<String, VariableInstance> variables = null;
        if (variableNames == null) {

            if (isLocal) {
                variables = task.getVariableInstancesLocal();
            } else {
                variables = task.getVariableInstances();
            }

        } else {
            if (isLocal) {
                variables = task.getVariableInstancesLocal(variableNames, false);
            } else {
                variables = task.getVariableInstances(variableNames, false);
            }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Re-validate task existence with createTaskQuery().taskId(id).singleResult() before fetching variables.
  2. Catch FlowableObjectNotFoundException and fall back to history APIs if the task may have finished.
  3. Confirm the engine configuration (datasource, tenant) matches where the task was created.
  4. Avoid caching task ids across long-running operations; resolve them fresh at use time.

Example fix

// before
Map<String, VariableInstance> vars = cmmnTaskService.getVariableInstances(taskId);
// after
Task task = cmmnTaskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
    throw new IllegalStateException("Task " + taskId + " no longer exists");
}
Map<String, VariableInstance> vars = cmmnTaskService.getVariableInstances(taskId);
Defensive patterns

Strategy: try-catch

Validate before calling

if (taskService.createTaskQuery().taskId(taskId).count() == 0) { return Collections.emptyMap(); }

Try / catch

try { return taskService.getVariableInstances(taskId); } catch (FlowableObjectNotFoundException e) { return Collections.emptyMap(); }

Prevention

When it happens

Trigger: Calling getVariableInstances(taskId)/getVariableInstancesLocal(taskId, names) where the task was completed/removed, the case instance was deleted, or the id never existed in this engine's database.

Common situations: Racing with task completion in another thread/node; stale ids stored in an external table; pointing a client at a test/prod database mismatch; referencing a task from an aborted case instance.

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