flowable/flowable-engine · error · FlowableIllegalArgumentException

taskId is null

Error message

taskId is null

What it means

GetTaskVariableInstancesCmd.execute() validates that a taskId was supplied before retrieving all variable instances for the task. A null taskId throws FlowableIllegalArgumentException('taskId is null') because the map of variables cannot be resolved without a task identifier.

Solutions

  1. Check taskId for null before calling getVariableInstances/getVariableInstancesLocal.
  2. Filter null/blank entries out of any id collection before iterating and calling the API per id.
  3. Fix the upstream source (query result, header, form data) that failed to supply the task id.

Example fix

// before
Map<String, VariableInstance> vars = cmmnTaskService.getVariableInstances(taskId);
// after
if (taskId != null) {
    Map<String, VariableInstance> vars = cmmnTaskService.getVariableInstances(taskId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (taskId == null) { throw new IllegalArgumentException("taskId is required"); }

Type guard

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

Try / catch

try { return taskService.getVariableInstances(taskId); } catch (FlowableIllegalArgumentException e) { return Collections.emptyMap(); }

Prevention

When it happens

Trigger: Calling cmmnTaskService.getVariableInstances(null) or getVariableInstancesLocal(null, variableNames); building GetTaskVariableInstancesCmd with a null id and executing it.

Common situations: Batch worker iterating task ids where one entry is null; task id extracted from an optional message/header that was absent; variable-scope resolution helper invoked without a bound task.

Related errors


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

Appendix: source

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

public class GetTaskVariableInstancesCmd implements Command<Map<String, VariableInstance>>, Serializable {

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

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

    @Override
    public Map<String, VariableInstance> 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);
        }

        Map<String, VariableInstance> variables = null;
        if (variableNames == null) {

            if (isLocal) {
                variables = task.getVariableInstancesLocal();
            } else {
                variables = task.getVariableInstances();
            }

View on GitHub (pinned to d6d39ce1c6)