flowable/flowable-engine · error · FlowableIllegalArgumentException

variableName is null

Error message

variableName is null

What it means

HasExecutionVariableCmd.execute() throws FlowableIllegalArgumentException("variableName is null") when the variable name argument is null. Even with a valid execution, the engine cannot test existence of an unnamed variable, so the argument is rejected up front.

Solutions

  1. Pass a non-null, correct variable name string to hasVariable/hasVariableLocal.
  2. Centralize variable names as constants and validate config files for missing name entries.
  3. Guard call sites that derive the name dynamically: skip or fail fast when the derived name is null.
  4. Catch FlowableIllegalArgumentException and report which variable name was missing.

Example fix

// before
boolean has = runtimeService.hasVariable(executionId, config.getVarName()); // may be null
// after
if (config.getVarName() == null) {
    throw new IllegalStateException("Variable name not configured");
}
boolean has = runtimeService.hasVariable(executionId, config.getVarName());
Defensive patterns

Strategy: validation

Validate before calling

if (variableName == null || variableName.isEmpty()) {
    throw new IllegalArgumentException("variableName must be provided");
}

Type guard

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

Try / catch

try {
    return runtimeService.hasVariable(executionId, variableName);
} catch (FlowableIllegalArgumentException e) {
    throw new BadRequestException("variableName is required", e);
}

Prevention

When it happens

Trigger: runtimeService.hasVariable(executionId, null) or hasVariableLocal(executionId, null), typically when the variable name comes from configuration or a dynamic map key that is missing.

Common situations: Variable names read from a properties/YAML config where the key was renamed or omitted; iterating a map with null keys; refactors renaming a constant but not all usages.

Related errors


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

Appendix: source

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

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

    public HasExecutionVariableCmd(String executionId, String variableName, boolean isLocal) {
        this.executionId = executionId;
        this.variableName = variableName;
        this.isLocal = isLocal;
    }

    @Override
    public Boolean execute(CommandContext commandContext) {
        if (executionId == null) {
            throw new FlowableIllegalArgumentException("executionId is null");
        }
        if (variableName == null) {
            throw new FlowableIllegalArgumentException("variableName is null");
        }

        ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId);

        if (execution == null) {
            throw new FlowableObjectNotFoundException("execution " + executionId + " doesn't exist", Execution.class);
        }

        boolean hasVariable = false;

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

        return hasVariable;
    }

View on GitHub (pinned to d6d39ce1c6)