flowable/flowable-engine · error · ActivitiIllegalArgumentException

taskId is null

Error message

taskId is null

What it means

NeedsActiveTaskCmd.execute() validates that a taskId was supplied before looking up the task, throwing ActivitiIllegalArgumentException when it is null. This is a programmer error: the command object was constructed without its required task identifier.

Solutions

  1. Ensure the calling task service method receives a non-null taskId; trace where the id is loaded (request param, task object) and fix the null source.
  2. Add an explicit null check or @NotNull validation at the API/controller boundary before invoking the engine.
  3. In tests, pass a real taskId obtained from taskService.createTaskQuery() instead of a placeholder null.

Example fix

// before
String taskId = request.getParameter("taskId");
taskService.complete(taskId);

// after
String taskId = request.getParameter("taskId");
if (taskId == null || taskId.isEmpty()) {
    throw new BadRequestException("taskId is required");
}
taskService.complete(taskId);
Defensive patterns

Strategy: validation

Validate before calling

if (taskId == null || taskId.trim().isEmpty()) throw new IllegalArgumentException("taskId is required");

Type guard

boolean hasTaskId(String taskId) { return taskId != null && !taskId.trim().isEmpty(); }

Try / catch

try {
    taskService.complete(taskId);
} catch (ActivitiIllegalArgumentException e) {
    log.error("Missing taskId");
}

Prevention

When it happens

Trigger: Constructing a task command (complete, claim, resolve, set assignee, add comment, etc.) with a null taskId, typically from an unbound request parameter or an uninitialized variable, then executing it via the command executor or a task service call.

Common situations: Web controllers binding an optional 'taskId' path/form parameter that is absent; refactoring that removed the id-population step; unit tests invoking commands directly with an incomplete constructor.

Related errors


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

Appendix: source

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

 * An abstract superclass for {@link Command} implementations that want to verify the provided task is always active (ie. not suspended).
 * 
 * @author Joram Barrez
 */
public abstract class NeedsActiveTaskCmd<T> implements Command<T>, Serializable {

    private static final long serialVersionUID = 1L;

    protected String taskId;

    public NeedsActiveTaskCmd(String taskId) {
        this.taskId = taskId;
    }

    @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);
    }

    /**

View on GitHub (pinned to d6d39ce1c6)