flowable/flowable-engine · error · ActivitiIllegalArgumentException

variable does not resolve to a boolean.

Error message

${skipExpressionEnabledVariable} variable does not resolve to a boolean. ${isSkipExpressionEnabled}

What it means

Thrown as ActivitiIllegalArgumentException from SkipExpressionUtil.isSkipExpressionEnabled when the variable named by skipExpressionEnabledVariable exists in the execution but does not resolve to a Boolean. The engine uses this variable as the master switch for skip expressions and requires a true/false value.

Solutions

  1. Set the variable as a real Boolean: execution.setVariable("_ACTIVITI_SKIP_EXPRESSION_ENABLED", Boolean.TRUE).
  2. If the value comes from a String, convert it before storing: Boolean.parseBoolean(value).
  3. Check the process/form/REST payload that writes the variable and ensure the type is boolean.
  4. Inspect the variable value in the error message — it prints the offending object — and fix its type at the source.

Example fix

// before: string value
execution.setVariable("_ACTIVITI_SKIP_EXPRESSION_ENABLED", "true");

// after: real boolean
execution.setVariable("_ACTIVITI_SKIP_EXPRESSION_ENABLED", Boolean.parseBoolean("true"));
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = execution.getVariable("_ACTIVITI_SKIP_EXPRESSION_ENABLED");
if (v != null && !(v instanceof Boolean)) {
    throw new IllegalStateException("Skip-enabled variable must be Boolean, got " + v.getClass());
}

Type guard

boolean isBooleanVariable(DelegateExecution execution, String name) {
    Object v = execution.getVariable(name);
    return v == null || v instanceof Boolean;
}

Try / catch

try {
    runtimeService.setVariable(executionId, "_ACTIVITI_SKIP_EXPRESSION_ENABLED", skipEnabled);
} catch (ActivitiIllegalArgumentException e) {
    logger.error("Skip-enabled variable must be a Boolean, value={}", skipEnabled, e);
    throw e;
}

Prevention

When it happens

Trigger: A DelegateExecution contains a variable whose value is a non-boolean (String, Integer, etc.) under the key stored in skipExpressionEnabledVariable (by default "_ACTIVITI_SKIP_EXPRESSION_ENABLED"), and SkipExpressionUtil.isSkipExpressionEnabled is called during execution of a job/activity with a skipExpression.

Common situations: Setting the skip-enabled variable via an expression or form field that yields a String "true" instead of Boolean true; passing the variable through a REST call where it gets serialized as a string; script tasks writing the variable with quotes; version differences where the variable was previously loosely coerced.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/SkipExpressionUtil.java:37

public class SkipExpressionUtil {

    public static boolean isSkipExpressionEnabled(DelegateExecution execution, Expression skipExpression) {

        if (skipExpression == null) {
            return false;
        }

        final String skipExpressionEnabledVariable = "_ACTIVITI_SKIP_EXPRESSION_ENABLED";
        Object isSkipExpressionEnabled = execution.getVariable(skipExpressionEnabledVariable);

        if (isSkipExpressionEnabled == null) {
            return false;

        } else if (isSkipExpressionEnabled instanceof Boolean) {
            return ((Boolean) isSkipExpressionEnabled).booleanValue();

        } else {
            throw new ActivitiIllegalArgumentException(skipExpressionEnabledVariable + " variable does not resolve to a boolean. " + isSkipExpressionEnabled);
        }
    }

    public static boolean shouldSkipFlowElement(DelegateExecution execution, Expression skipExpression) {
        Object value = skipExpression.getValue(execution);

        if (value instanceof Boolean) {
            return ((Boolean) value).booleanValue();

        } else {
            throw new ActivitiIllegalArgumentException("Skip expression does not resolve to a boolean: " + skipExpression.getExpressionText());
        }
    }
}

View on GitHub (pinned to d6d39ce1c6)