flowable/flowable-engine · error · FlowableException

Cannot add a comment to a suspended {task}

Error message

Cannot add a comment to a suspended {task}

What it means

FlowableException thrown by AddCommentCmd.execute when the referenced task exists but is suspended. The engine forbids mutating suspended tasks, including adding comments, until the task or its process instance is activated.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AddCommentCmd.java:69

        this.processInstanceId = processInstanceId;
        this.type = type;
        this.message = message;
    }

    @Override
    public Comment execute(CommandContext commandContext) {
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        TaskEntity task = null;
        // Validate task
        if (taskId != null) {
            task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);

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

            if (task.isSuspended()) {
                throw new FlowableException("Cannot add a comment to a suspended " + task);
            }
        }

        ExecutionEntity execution = null;
        if (processInstanceId != null) {
            execution = processEngineConfiguration.getExecutionEntityManager().findById(processInstanceId);

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

            if (execution.isSuspended()) {
                throw new FlowableException("Cannot add a comment to a suspended " + execution);
            }
        }

        String processDefinitionId = null;
        if (execution != null) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Activate the task first: taskService.activateTask(taskId), then add the comment.
  2. Activate the owning process instance: runtimeService.activateProcessInstanceById(piId).
  3. Check task.isSuspended() before attempting to comment and defer the comment until re-activation.
  4. Catch FlowableException and queue the comment for delivery after suspension is lifted.

Example fix

// before
taskService.addComment(taskId, null, msg);
// after
if (taskService.createTaskQuery().taskId(taskId).active().singleResult() != null) {
    taskService.addComment(taskId, null, msg);
} else {
    taskService.activateTask(taskId);
    taskService.addComment(taskId, null, msg);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (taskService.createTaskQuery().taskId(taskId).suspended().singleResult() != null) {
    taskService.activateTask(taskId); // or defer the comment
}

Try / catch

try {
    taskService.addComment(taskId, null, msg);
} catch (FlowableException e) {
    // queue comment; retry after task is activated
    commentQueue.add(new PendingComment(taskId, msg));
}

Prevention

When it happens

Trigger: taskService.addComment(taskId, ...) on a task under a suspended process instance or definition, or after taskService.suspendTask(taskId).

Common situations: Administrative suspension (e.g. pending approval fix) while users/automation still try to comment; batch comment jobs running during a suspension window.

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