flowable/flowable-engine · error · FlowableIllegalArgumentException

variableName is null

Error message

variableName is null

What it means

HasTaskVariableCmd.execute throws FlowableIllegalArgumentException when variableName is null. The task id passed validation, but a null variable name cannot be tested against the task's variables, so the command rejects it before fetching the task.

Source

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

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

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

    @Override
    public Boolean 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);
        }
        boolean hasVariable = false;

        if (isLocal) {
            hasVariable = task.hasVariableLocal(variableName);
        } else {
            hasVariable = task.hasVariable(variableName);
        }

        return hasVariable;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Validate the variable name before the call
  2. Fix the configuration/source producing the null name
  3. Use constants/enums for variable names

Example fix

// before
boolean has = taskService.hasVariable(taskId, name);
// after
Objects.requireNonNull(name, "variableName required");
boolean has = taskService.hasVariable(taskId, name);
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

boolean validVariableName(String name) {
    return name != null && !name.trim().isEmpty();
}

Try / catch

try {
    return taskService.hasVariable(taskId, variableName);
} catch (FlowableIllegalArgumentException e) {
    log.error("Missing variableName: {}", e.getMessage());
    return false;
}

Prevention

When it happens

Trigger: Calling hasVariable(taskId, null) or hasVariableLocal(taskId, null), usually because the name came from missing config, a null map key, or an unset field.

Common situations: Variable names externalized to configuration that is missing, dynamic names built from user input that is absent, refactoring removing a constant value.

Related errors


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