flowable/flowable-engine · error · ActivitiIllegalArgumentException

taskId is null

Error message

taskId is null

What it means

GetTaskVariablesCmd.execute rejects a null taskId with ActivitiIllegalArgumentException before querying the task table. It is the batch (all-variables) counterpart of the single-variable guard. Always a caller-side null-propagation bug.

Solutions

  1. Null-check taskId before calling getVariables/getVariablesLocal.
  2. Trace why the id was null: unbound input, failed deserialization, or an earlier exception swallowed.
  3. Return a client-side validation error instead of hitting the engine.
  4. For optional tasks, query existence first and short-circuit.

Example fix

// before
Map<String, Object> vars = taskService.getVariables(taskId);
// after
Objects.requireNonNull(taskId, "taskId must not be null");
Map<String, Object> vars = taskService.getVariables(taskId);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(taskId, "taskId must not be null");

Try / catch

try {
    return taskService.getVariables(taskId);
} catch (ActivitiIllegalArgumentException e) {
    return Collections.emptyMap();
}

Prevention

When it happens

Trigger: Calling taskService.getVariables(taskId) or getVariablesLocal(taskId) with null taskId, e.g. when the id field of a task DTO was never populated.

Common situations: Deserializing task payloads where taskId was absent; code paths executed before a task was actually created; optional form submissions leaving the id blank.

Related errors


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

Appendix: source

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

 * @author Joram Barrez
 */
public class GetTaskVariablesCmd implements Command<Map<String, Object>>, Serializable {

    private static final long serialVersionUID = 1L;
    protected String taskId;
    protected Collection<String> variableNames;
    protected boolean isLocal;

    public GetTaskVariablesCmd(String taskId, Collection<String> variableNames, boolean isLocal) {
        this.taskId = taskId;
        this.variableNames = variableNames;
        this.isLocal = isLocal;
    }

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {
        if (taskId == null) {
            throw new ActivitiIllegalArgumentException("taskId is null");
        }

        TaskEntity task = commandContext
                .getTaskEntityManager()
                .findTaskById(taskId);

        if (task == null) {
            throw new ActivitiObjectNotFoundException("task " + taskId + " doesn't exist", Task.class);
        }

        if (variableNames == null) {

            if (isLocal) {
                return task.getVariablesLocal();
            } else {
                return task.getVariables();
            }

View on GitHub (pinned to d6d39ce1c6)