flowable/flowable-engine · error · ActivitiException

Cannot execute operation: task is suspended

Error message

Cannot execute operation: task is suspended

What it means

The task exists but is suspended (its process instance or definition was suspended), so NeedsActiveTaskCmd.execute() blocks the operation with getSuspendedTaskException(). User tasks inherit suspension from their process instance/definition; no task-level operation is allowed until activation.

Solutions

  1. Activate the process instance: runtimeService.activateProcessInstanceById(processInstanceId) (or the definition-level activate variant).
  2. Check the task's suspended flag beforehand: task.isSuspended() on the fetched Task, or via the task query, and disable the action in the UI.
  3. If suspension is intentional, defer the task operation (queue it) until the instance is reactivated.
  4. Exclude suspended tasks from worker/bot queries using .suspended().exclude... query filters.

Example fix

// before
taskService.claim(taskId, userId);

// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task != null && !task.isSuspended()) {
    taskService.claim(taskId, userId);
} else if (task != null) {
    runtimeService.activateProcessInstanceById(task.getProcessInstanceId());
    taskService.claim(taskId, userId);
}
Defensive patterns

Strategy: validation

Validate before calling

Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task != null && task.isSuspended()) throw new IllegalStateException("task suspended: " + taskId);

Try / catch

try {
    taskService.complete(taskId);
} catch (ActivitiException e) {
    if (e.getMessage() != null && e.getMessage().contains("suspended")) {
        // defer or notify, or activate the process instance
    }
}

Prevention

When it happens

Trigger: taskService.complete, claim, delegate, resolve, setAssignee, etc. while the owning process instance was suspended via runtimeService.suspendProcessInstanceById or the definition via repositoryService.suspendProcessDefinition... with suspendProcessInstances=true.

Common situations: Definition suspended during a maintenance window so all in-flight user tasks freeze; a user completes a task from a stale worklist after an admin suspended the instance; automated claims by bots hitting suspended tasks.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/d7c846b2ddbab91d. Report an issue: GitHub.

Appendix: source

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

    }

    @Override
    public T execute(CommandContext commandContext) {

        if (taskId == null) {
            throw new ActivitiIllegalArgumentException("taskId is null");
        }

        TaskEntity task = commandContext
                .getTaskEntityManager()
                .findTaskById(taskId);

        if (task == null) {
            throw new ActivitiObjectNotFoundException("Cannot find task with id " + taskId, Task.class);
        }

        if (task.isSuspended()) {
            throw new ActivitiException(getSuspendedTaskException());
        }

        return execute(commandContext, task);
    }

    /**
     * Subclasses must implement in this method their normal command logic. The provided task is ensured to be active.
     */
    protected abstract T execute(CommandContext commandContext, TaskEntity task);

    /**
     * Subclasses can override this method to provide a customized exception message that will be thrown when the task is suspended.
     */
    protected String getSuspendedTaskException() {
        return "Cannot execute operation: task is suspended";
    }

}

View on GitHub (pinned to d6d39ce1c6)