flowable/flowable-engine · error · FlowableIllegalArgumentException

taskId is null

Error message

taskId is null

What it means

GetTaskVariableInstanceCmd.execute() validates its command arguments before doing any work. When the taskId passed to the command is null, it throws FlowableIllegalArgumentException('taskId is null') because a task variable instance cannot be looked up without a task id. This is a fail-fast guard protecting the downstream task service query from a pointless or dangerous null lookup.

Solutions

  1. Ensure a non-null taskId is passed: verify the value before calling taskService.getVariableInstance/getVariableInstanceLocal.
  2. If the taskId came from a previous query result, check that result for null/empty before using it.
  3. Fix the upstream data source (form field, process variable, request parameter) that produced a missing task id.

Example fix

// before
VariableInstance vi = cmmnTaskService.getVariableInstance(taskId, "status");
// after
if (taskId == null) {
    throw new IllegalArgumentException("taskId must be resolved before fetching variables");
}
VariableInstance vi = cmmnTaskService.getVariableInstance(taskId, "status");
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Try / catch

try { return taskService.getVariableInstance(taskId, name); } catch (FlowableIllegalArgumentException e) { log.error("Bad argument: {}", e.getMessage()); throw e; }

Prevention

When it happens

Trigger: Calling CmmnTaskService.getVariableInstance(taskId, variableName) or getVariableInstanceLocal(taskId, variableName) with a null taskId; constructing GetTaskVariableInstanceCmd(null, name, isLocal) directly and executing it.

Common situations: taskId obtained from an unresolved/failed prior API call (e.g. task == null from a createTask/query result) and passed on unguarded; a Map- or form-sourced task id that was never populated; refactoring that dropped a null check between fetching and using the id.

Related errors


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

Appendix: source

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

public class GetTaskVariableInstanceCmd implements Command<VariableInstance>, Serializable {

    private static final long serialVersionUID = 1L;
    
    protected String taskId;
    protected String variableName;
    protected boolean isLocal;

    public GetTaskVariableInstanceCmd(String taskId, String variableName, boolean isLocal) {
        this.taskId = taskId;
        this.variableName = variableName;
        this.isLocal = isLocal;
    }

    @Override
    public VariableInstance execute(CommandContext commandContext) {
        if (taskId == null) {
            throw new FlowableIllegalArgumentException("taskId is null");
        }
        if (variableName == null) {
            throw new FlowableIllegalArgumentException("variableName 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);
        }

        VariableInstance variableEntity;

        if (isLocal) {
            variableEntity = task.getVariableInstanceLocal(variableName, false);
        } else {
            variableEntity = task.getVariableInstance(variableName, false);

View on GitHub (pinned to d6d39ce1c6)