flowable/flowable-engine · error · FlowableObjectNotFoundException

execution ${executionId} doesn't exist

Error message

execution ${executionId} doesn't exist

What it means

Flowable throws FlowableObjectNotFoundException when the executionId passed to GetExecutionVariableInstancesCmd refers to no existing execution. The id passes the null check but findById returns null, meaning the execution row is absent. Message: 'execution <id> doesn't exist'.

Source

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

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

    @Override
    public Map<String, VariableInstance> execute(CommandContext commandContext) {

        // Verify existence of execution
        if (executionId == null) {
            throw new FlowableIllegalArgumentException("executionId is null");
        }

        ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId);

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

        Map<String, VariableInstance> variables = null;

        if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, execution.getProcessDefinitionId())) {
            Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();
            variables = compatibilityHandler.getExecutionVariableInstances(executionId, variableNames, isLocal);

        } else {

            if (variableNames == null || variableNames.isEmpty()) {
                // Fetch all
                if (isLocal) {
                    variables = execution.getVariableInstancesLocal();
                } else {
                    variables = execution.getVariableInstances();
                }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Confirm the execution exists via RuntimeService#createExecutionQuery before querying variables
  2. Look up variables from the process instance id which survives via history, or enable history to retrieve past variables
  3. Catch FlowableObjectNotFoundException and handle the 'execution gone' case explicitly
  4. Verify the same database/engine is being queried

Example fix

// before
Map<String, VariableInstance> vars = runtimeService.getVariableInstances(executionId);
// after
Execution e = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (e == null) throw new IllegalStateException("Execution gone: " + executionId);
Map<String, VariableInstance> vars = runtimeService.getVariableInstances(executionId);
Defensive patterns

Strategy: try-catch

Validate before calling

Execution e = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (e == null) throw new IllegalStateException("Execution not found: " + executionId);

Try / catch

try { ... } catch (FlowableObjectNotFoundException e) { /* execution gone — fallback to history or empty map */ }

Prevention

When it happens

Trigger: RuntimeService.getVariableInstances(deletedExecutionId); id from a process instance that already ended; typo'd or truncated id; wrong engine datasource.

Common situations: Long-running integrations storing ids in external tables past the process lifetime; test data cleanup; database switch between environments.

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