flowable/flowable-engine · error · FlowableIllegalArgumentException

caseInstanceId is null

Error message

caseInstanceId is null

What it means

HasCaseInstanceVariableCmd.execute throws FlowableIllegalArgumentException when caseInstanceId is null. The command first validates its required arguments, then checks the case instance exists, before testing whether the variable is present. A null id cannot be resolved to any case instance, so it is rejected immediately.

Source

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

 * @author Tijs Rademakers
 */
public class HasCaseInstanceVariableCmd implements Command<Boolean>, Serializable {

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

    public HasCaseInstanceVariableCmd(String caseInstanceId, String variableName, boolean isLocal) {
        this.caseInstanceId = caseInstanceId;
        this.variableName = variableName;
        this.isLocal = isLocal;
    }

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

        CaseInstanceEntity caseInstance = CommandContextUtil.getCaseInstanceEntityManager(commandContext).findById(caseInstanceId);

        if (caseInstance == null) {
            throw new FlowableObjectNotFoundException("case instance " + caseInstanceId + " doesn't exist", CaseInstance.class);
        }

        boolean hasVariable = false;

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

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify caseInstanceId is populated before the call; trace its source
  2. Resolve the id via a CaseInstanceQuery and handle the no-match case first
  3. Wrap the call in a null check or use an Optional around the id

Example fix

// before
boolean has = cmmnRuntimeService.hasVariable(caseInstanceId, "approved");
// after
boolean has = caseInstanceId != null && cmmnRuntimeService.hasVariable(caseInstanceId, "approved");
Defensive patterns

Strategy: validation

Validate before calling

if (caseInstanceId == null) {
    throw new IllegalArgumentException("caseInstanceId is required for hasVariable");
}

Type guard

boolean validId(String id) {
    return id != null && !id.isEmpty();
}

Try / catch

try {
    return cmmnRuntimeService.hasVariable(caseInstanceId, variableName);
} catch (FlowableIllegalArgumentException e) {
    log.warn("Invalid hasVariable arguments: {}", e.getMessage());
    return false;
}

Prevention

When it happens

Trigger: Calling cmmnRuntimeService.hasVariable(null, variableName) or hasVariableLocal(null, variableName), or building the command directly with a null caseInstanceId.

Common situations: Chained lookups where an earlier query returned null, passing an uninitialized field from a delegation class, or copy/paste code where the id variable was renamed but not initialized.

Related errors


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