flowable/flowable-engine · error · FlowableException

a suspended

Error message

 a suspended 

What it means

NeedsActiveTaskCmd.execute() refuses to run the operation on a suspended task, throwing FlowableException with prefix from getSuspendedTaskExceptionPrefix() plus ' a suspended ' + task. The command subclasses define the prefix (e.g. 'Cannot complete'), so the full message reads like 'Cannot complete a suspended TaskEntity ...'. This enforces that active-only task commands are not applied to suspended tasks.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/NeedsActiveTaskCmd.java:57

        this.taskId = taskId;
    }

    @Override
    public T execute(CommandContext commandContext) {

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

        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        TaskEntity task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);

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

        if (task.isSuspended()) {
            throw new FlowableException(getSuspendedTaskExceptionPrefix() + " a suspended " + task);
        }

        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 getSuspendedTaskExceptionPrefix() {
        return "Cannot execute operation for";
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Activate the case instance first via CaseRuntimeService.activateCaseInstance(caseInstanceId), then retry the task command
  2. Filter out suspended tasks: taskService.createTaskQuery().suspended().list() tells you which to skip; query with .active() for workable tasks
  3. Catch FlowableException and check the message prefix to surface 'task is suspended' to the user

Example fix

// before
taskService.complete(taskId); // throws: Cannot complete a suspended ...
// after
cmmnRuntimeService.activateCaseInstance(caseInstanceId);
taskService.complete(taskId);
Defensive patterns

Strategy: try-catch

Validate before calling

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

Try / catch

try { taskService.complete(taskId); } catch (FlowableException e) { if (e.getMessage().contains("a suspended")) { /* activate scope or skip task */ } }

Prevention

When it happens

Trigger: Calling taskService.complete/claim/resolve etc. on a task whose case instance (or scope) was suspended — task.isSuspended() returns true — while the command requires an active task.

Common situations: A case instance was suspended by an administrator and users keep acting on its tasks in the UI; batch jobs processing task lists that include tasks from suspended scopes; after undeploying/suspending definitions.

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