flowable/flowable-engine · error · FlowableObjectNotFoundException

Cannot find processInstance for id '{processInstanceId}'.

Error message

Cannot find processInstance for id '{processInstanceId}'.

What it means

FlowableObjectNotFoundException thrown by AbstractSetProcessInstanceStateCmd.execute when no execution entity exists in ACT_RU_EXECUTION for the given processInstanceId. The activate/suspend process instance command looks up the root execution first; if the id is unknown or the instance has ended, it aborts with this error rather than silently succeeding. The exception carries Execution.class as the referenced entity type.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AbstractSetProcessInstanceStateCmd.java:64

    protected final String processInstanceId;

    public AbstractSetProcessInstanceStateCmd(String processInstanceId) {
        this.processInstanceId = processInstanceId;
    }

    @Override
    public Void execute(CommandContext commandContext) {

        if (processInstanceId == null) {
            throw new FlowableIllegalArgumentException("ProcessInstanceId cannot be null.");
        }

        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        ExecutionEntityManager executionEntityManager = processEngineConfiguration.getExecutionEntityManager();
        ExecutionEntity executionEntity = executionEntityManager.findById(processInstanceId);

        if (executionEntity == null) {
            throw new FlowableObjectNotFoundException("Cannot find processInstance for id '" + processInstanceId + "'.", Execution.class);
        }
        if (!executionEntity.isProcessInstanceType()) {
            throw new FlowableException("Cannot set suspension state for execution '" + executionEntity + "': not a process instance.");
        }

        if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, executionEntity.getProcessDefinitionId())) {
            if (getNewState() == SuspensionState.ACTIVE) {
                processEngineConfiguration.getFlowable5CompatibilityHandler().activateProcessInstance(processInstanceId);
            } else {
                processEngineConfiguration.getFlowable5CompatibilityHandler().suspendProcessInstance(processInstanceId);
            }
            return null;
        }

        SuspensionStateUtil.setSuspensionState(executionEntity, getNewState());
        executionEntityManager.update(executionEntity, false);

        // All child executions are suspended

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the id is a real process instance id: runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult() != null.
  2. Use the result of runtimeService.startProcessInstanceByKey(...) directly instead of reconstructing the id.
  3. If the instance already ended, use HistoryService to inspect it rather than changing suspension state.
  4. Check you are not swapping processDefinitionId/processInstanceId arguments; use suspendProcessInstanceByKey for definition-level suspension.

Example fix

// before
runtimeService.suspendProcessInstanceById(processDefinitionId);
// after
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
    .processInstanceId(processInstanceId).singleResult();
if (pi != null) {
    runtimeService.suspendProcessInstanceById(pi.getId());
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult() == null) {
    throw new IllegalArgumentException("Unknown process instance: " + id);
}

Try / catch

try {
    runtimeService.suspendProcessInstanceById(id);
} catch (FlowableObjectNotFoundException e) {
    // instance missing or already ended; log and continue
}

Prevention

When it happens

Trigger: Calling runtimeService.activateProcessInstanceById(id) or suspendProcessInstanceById(id) with an id that does not exist, has been deleted, or references a completed/historic process instance.

Common situations: Passing a processDefinitionId instead of a processInstanceId; storing ids across a database reset; operating on an instance that finished between fetch and activation; typos or stale ids from external persistence.

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