flowable/flowable-engine · warning · FlowableIllegalArgumentException

variables is empty

Error message

variables is empty

What it means

SetVariablesCmd rejects an empty variables map because setting zero variables is a no-op that usually indicates a caller bug. After the null and caseInstanceId checks, an empty map triggers FlowableIllegalArgumentException.

Source

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

    
    protected String caseInstanceId;
    protected Map<String, Object> variables;
    
    public SetVariablesCmd(String caseInstanceId, Map<String, Object> variables) {
        this.caseInstanceId = caseInstanceId;
        this.variables = variables;
    }
    
    @Override
    public Void execute(CommandContext commandContext) {
        if (caseInstanceId == null) {
            throw new FlowableIllegalArgumentException("caseInstanceId is null");
        }
        if (variables == null) {
            throw new FlowableIllegalArgumentException("variables is null");
        }
        if (variables.isEmpty()) {
            throw new FlowableIllegalArgumentException("variables is empty");
        }
     
        CaseInstanceEntity caseInstanceEntity = CommandContextUtil.getCaseInstanceEntityManager(commandContext).findById(caseInstanceId);
        if (caseInstanceEntity == null) {
            throw new FlowableObjectNotFoundException("No case instance found for id " + caseInstanceId, CaseInstanceEntity.class);
        }
        caseInstanceEntity.setVariables(variables);
        
        Set<String> variableNames = variables.keySet();
        
        CmmnEngineAgenda agenda = CommandContextUtil.getAgenda(commandContext);
        
        CmmnDeploymentManager deploymentManager = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getDeploymentManager();
        CaseDefinition caseDefinition = deploymentManager.findDeployedCaseDefinitionById(caseInstanceEntity.getCaseDefinitionId());
        boolean evaluateVariableEventListener = false;
        if (caseDefinition != null) {
            CmmnModel cmmnModel = deploymentManager.resolveCaseDefinition(caseDefinition).getCmmnModel();
            for (Case caze : cmmnModel.getCases()) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Guard the call: only invoke setVariables when !variables.isEmpty().
  2. Fix upstream logic that produces an empty map (validate request payload keys).
  3. If a no-op is acceptable, check emptiness first and return early.

Example fix

// before
runtimeService.setVariables(caseInstanceId, variables); // may be empty
// after
if (!variables.isEmpty()) {
    runtimeService.setVariables(caseInstanceId, variables);
}
Defensive patterns

Strategy: validation

Validate before calling

if (variables == null || variables.isEmpty()) return; // no-op guard

Try / catch

try {
    runtimeService.setVariables(caseInstanceId, vars);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("variables is empty")) {
        // treat as no-op
    }
}

Prevention

When it happens

Trigger: Calling CmmnRuntimeService.setVariables(caseInstanceId, Collections.emptyMap()) or with a map whose entries were all filtered out before the call.

Common situations: Building variables conditionally so all keys are removed; passing a deserialized/empty payload from a REST request; looping that ends with nothing left to set.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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