flowable/flowable-engine · error · FlowableObjectNotFoundException

execution ${executionId} doesn't exist

Error message

execution ${executionId} doesn't exist

What it means

When the executionId is non-null but ExecutionEntityManager.findById finds no execution, the command throws FlowableObjectNotFoundException. The id refers to an execution that never existed or no longer exists.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/FindActiveActivityIdsCmd.java:52

    private static final long serialVersionUID = 1L;
    protected String executionId;

    public FindActiveActivityIdsCmd(String executionId) {
        this.executionId = executionId;
    }

    @Override
    public List<String> execute(CommandContext commandContext) {
        if (executionId == null) {
            throw new FlowableIllegalArgumentException("executionId is null");
        }

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

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

        return findActiveActivityIds(execution);
    }

    public List<String> findActiveActivityIds(ExecutionEntity executionEntity) {
        List<String> activeActivityIds = new ArrayList<>();
        collectActiveActivityIds(executionEntity, activeActivityIds);
        return activeActivityIds;
    }

    protected void collectActiveActivityIds(ExecutionEntity executionEntity, List<String> activeActivityIds) {
        if (executionEntity.isActive() && executionEntity.getActivityId() != null) {
            activeActivityIds.add(executionEntity.getActivityId());
        }

        for (ExecutionEntity childExecution : executionEntity.getExecutions()) {
            collectActiveActivityIds(childExecution, activeActivityIds);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Check existence first with runtimeService.createExecutionQuery().executionId(id).singleResult()
  2. If the instance may have ended, fall back to historyService.createHistoricActivityInstanceQuery().executionId(id)
  3. Verify the id and the datasource/engine you are connected to

Example fix

// before
List<String> ids = runtimeService.getActiveActivityIds(id);
// after
Execution exec = runtimeService.createExecutionQuery().executionId(id).singleResult();
List<String> ids = exec != null ? runtimeService.getActiveActivityIds(id)
    : historyService.createHistoricActivityInstanceQuery().executionId(id).list()
        .stream().map(HistoricActivityInstance::getActivityId).toList();
Defensive patterns

Strategy: validation

Validate before calling

Execution exec = runtimeService.createExecutionQuery().executionId(id).singleResult();
if (exec == null) throw new IllegalArgumentException("execution not found: " + id);

Type guard

boolean isActiveExecution(String id) { return runtimeService.createExecutionQuery().executionId(id).count() > 0; }

Try / catch

try { ... } catch (FlowableObjectNotFoundException e) { if (e.getEntityClass() == Execution.class) { /* fall back to history query */ } else throw e; }

Prevention

When it happens

Trigger: runtimeService.getActiveActivityIds(id) with an id of a completed or deleted process instance, a mistyped id, or an id from a different engine database.

Common situations: Querying active activities after the instance finished; historical dashboards caching execution ids past their lifetime; multi-engine environments hitting the wrong datasource.

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