flowable/flowable-engine · error · ActivitiObjectNotFoundException

execution doesn't exist

Error message

execution  doesn't exist

What it means

After findExecutionById(executionId) returns null, GetExecutionVariableCmd throws ActivitiObjectNotFoundException("execution " + executionId + " doesn't exist", Execution.class). The id was well-formed but no matching execution row exists, typically because the process instance already ended or was deleted.

Solutions

  1. Verify the process is still running: runtimeService.createProcessInstanceQuery().processInstanceId(pid).singleResult() != null.
  2. For ended instances, read variables from history: historyService.createHistoricVariableInstanceQuery().executionId(executionId).list().
  3. Handle ActivitiObjectNotFoundException explicitly around the call if racing termination is possible.

Example fix

// before
Object value = runtimeService.getVariable(executionId, "status"); // ObjectNotFound if ended
// after
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
    .processInstanceId(processInstanceId).singleResult();
Object value = (pi != null)
    ? runtimeService.getVariable(executionId, "status")
    : historyService.createHistoricVariableInstanceQuery()
        .executionId(executionId).variableName("status").singleResult().getValue();
Defensive patterns

Strategy: try-catch

Validate before calling

boolean running = runtimeService.createExecutionQuery().executionId(executionId).count() > 0;
if (!running) {
    // fall back to historyService for ended instances
}

Try / catch

try {
    return runtimeService.getVariable(executionId, variableName);
} catch (ActivitiObjectNotFoundException e) {
    HistoricVariableInstance h = historyService.createHistoricVariableInstanceQuery()
        .executionId(executionId).variableName(variableName).singleResult();
    return h != null ? h.getValue() : null;
}

Prevention

When it happens

Trigger: runtimeService.getVariable(executionId, name) with an id of a finished, canceled, or deleted process instance/execution.

Common situations: Reading variables after process completion; stale execution id stored across a long delay; concurrent termination (boundary event, deleteProcessInstance) between obtaining and using the id.

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

Appendix: source

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

        this.variableName = variableName;
        this.isLocal = isLocal;
    }

    @Override
    public Object execute(CommandContext commandContext) {
        if (executionId == null) {
            throw new ActivitiIllegalArgumentException("executionId is null");
        }
        if (variableName == null) {
            throw new ActivitiIllegalArgumentException("variableName is null");
        }

        ExecutionEntity execution = commandContext
                .getExecutionEntityManager()
                .findExecutionById(executionId);

        if (execution == null) {
            throw new ActivitiObjectNotFoundException("execution " + executionId + " doesn't exist", Execution.class);
        }

        Object value;

        if (isLocal) {
            value = execution.getVariableLocal(variableName, false);
        } else {
            value = execution.getVariable(variableName, false);
        }

        return value;
    }
}

View on GitHub (pinned to d6d39ce1c6)