flowable/flowable-engine · error · ActivitiException

A delegated task cannot be completed, but should be resolved

Error message

A delegated task cannot be completed, but should be resolved instead.

What it means

TaskEntity.complete throws this when the task's delegationState is DelegationState.PENDING, i.e. the task was delegated to the assignee via TaskService.delegateTask and has not been resolved yet. A delegated task must go through TaskService.resolveTask, not complete, to preserve the delegation protocol. Completing it would silently discard the delegater's involvement.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/TaskEntity.java:189

                    EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);
        }
    }

    /**
     * Creates a new task. Embedded state and create time will be initialized. But this task still will have to be persisted. See {@link #insert(ExecutionEntity))}.
     */
    public static TaskEntity create(Date createTime) {
        TaskEntity task = new TaskEntity();
        task.isIdentityLinksInitialized = true;
        task.createTime = createTime;
        return task;
    }

    @SuppressWarnings("rawtypes")
    public void complete(Map variablesMap, boolean localScope, boolean fireEvents) {

        if (getDelegationState() != null && getDelegationState() == DelegationState.PENDING) {
            throw new ActivitiException("A delegated task cannot be completed, but should be resolved instead.");
        }

        if (fireEvents) {
            fireEvent(TaskListener.EVENTNAME_COMPLETE);
        }

        if (Authentication.getAuthenticatedUserId() != null && processInstanceId != null) {
            getProcessInstance().involveUser(Authentication.getAuthenticatedUserId(), IdentityLinkType.PARTICIPANT);
        }

        if (Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled() && fireEvents) {
            Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
                    ActivitiEventBuilder.createEntityWithVariablesEvent(FlowableEngineEventType.TASK_COMPLETED, this, variablesMap, localScope),
                    EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);
        }

        Context
                .getCommandContext()

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Call taskService.resolveTask(taskId) instead of complete() for delegated tasks
  2. Check task.getDelegationState() == DelegationState.RESOLVED (or null) before completing in UI/service logic
  3. If the delegation is no longer wanted, have the delegater resolve the task first, then complete it

Example fix

// before
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
taskService.complete(taskId);
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task.getDelegationState() == DelegationState.PENDING) {
    taskService.resolveTask(taskId, vars);
} else {
    taskService.complete(taskId, vars);
}
Defensive patterns

Strategy: validation

Validate before calling

Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
boolean completable = t == null || t.getDelegationState() != DelegationState.PENDING;

Prevention

When it happens

Trigger: Calling taskService.complete(taskId) (or RuntimeData task completion paths that call TaskEntity.complete) on a task that is currently in PENDING delegation state after a prior delegateTask call.

Common situations: UI shows a 'complete' button for a delegated task; batch scripts completing all tasks assigned to a user without checking delegation state; task was delegated and the assignee tries to finish it instead of resolving it back.

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