flowable/flowable-engine · error · FlowableIllegalArgumentException

taskId is null

Error message

taskId is null

What it means

GetTaskVariablesCmd.execute() is the fail-fast guard for the typed variable map API: with a null taskId it throws FlowableIllegalArgumentException('taskId is null'), since no variable map can be built without a task identifier.

Solutions

  1. Null-check the taskId before calling getVariables/getVariablesLocal.
  2. Assert the id was produced by a prior task-creation/query step before using it.
  3. Log and skip tasks with missing ids in batch loops instead of passing null through.

Example fix

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

Strategy: validation

Validate before calling

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

Type guard

boolean taskIdPresent(String taskId) { return taskId != null; }

Try / catch

try { return taskService.getVariables(taskId); } catch (FlowableIllegalArgumentException e) { log.error("taskId missing: {}", e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Calling cmmnTaskService.getVariables(null) or getVariablesLocal(null, variableNames/isLocal variants); executing a directly constructed GetTaskVariablesCmd with a null id.

Common situations: Null propagated from an optional lookup (e.g. Map.get returning null used as the task id); deserialized DTO with a missing id field; integration code where the assignment step was skipped so no task id was captured.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/GetTaskVariablesCmd.java:50

 */
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 FlowableIllegalArgumentException("taskId is null");
        }

        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        TaskEntity task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);

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

        if (variableNames == null) {

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

        } else {

View on GitHub (pinned to d6d39ce1c6)