flowable/flowable-engine · error · FlowableCdiException

Error while completing task:

Error message

Error while completing task: 

What it means

CompleteTaskInterceptor wraps methods annotated with @CompleteTask; after the intercepted method runs it completes the associated task via BusinessProcess.completeTask(). If completing the task throws any checked exception (wrapped by CDI in InvocationTargetException), the interceptor rethrows it as FlowableCdiException with the cause's message prefixed by 'Error while completing task: '.

Solutions

  1. Inspect e.getCause() (the wrapped FlowableException) to find the real failure; the outer message is only a prefix.
  2. Guard against double completion: check taskService.createTaskQuery().taskId(id).singleResult() != null, or catch and treat FlowableTaskAlreadyClaimed/TaskNotFoundException as idempotent.
  3. Ensure an active CDI conversation/scope with an associated task (BusinessProcess.associateTask(task)) before invoking the annotated method.

Example fix

// before
@CompleteTask
public void finish() { ... } // task may already be completed
// after
@CompleteTask
public void finish() {
    if (taskService.createTaskQuery().taskId(taskId).singleResult() == null) return;
    ...
}
Defensive patterns

Strategy: try-catch

Validate before calling

Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
boolean completable = t != null;

Type guard

null

Try / catch

try { businessProcess.completeTask(true); } catch (FlowableCdiException e) { log.error("complete failed", e.getCause()); if (!isTaskStillOpen(taskId)) { /* treat as idempotent success */ } }

Prevention

When it happens

Trigger: A @CompleteTask-annotated business method finishes and BusinessProcess.completeTask(endConversation) fails — e.g. the task was already completed or deleted, the associated execution ended, or the engine throws while flushing variable changes; the original exception's getMessage() is null so the message ends with just the prefix.

Common situations: Concurrent completion of the same task (user double-submits a form), task completed earlier in the same transaction, missing or inactive CDI context so no task is associated, or optimistic-locking exceptions from concurrent process updates.

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

Appendix: source

Thrown at modules/flowable-cdi/src/main/java/org/flowable/cdi/impl/annotation/CompleteTaskInterceptor.java:52

public class CompleteTaskInterceptor implements Serializable {

    private static final long serialVersionUID = 1L;

    @Inject
    BusinessProcess businessProcess;

    @AroundInvoke
    public Object invoke(InvocationContext ctx) throws Exception {
        try {
            Object result = ctx.proceed();

            CompleteTask completeTaskAnnotation = ctx.getMethod().getAnnotation(CompleteTask.class);
            boolean endConversation = completeTaskAnnotation.endConversation();
            businessProcess.completeTask(endConversation);

            return result;
        } catch (InvocationTargetException e) {
            throw new FlowableCdiException("Error while completing task: " + e.getCause().getMessage(), e.getCause());
        }
    }

}

View on GitHub (pinned to d6d39ce1c6)