flowable/flowable-engine · error · FlowableIllegalArgumentException
Skip expression variable does not resolve to a boolean. " +
Error message
Skip expression variable does not resolve to a boolean. " + isSkipExpressionEnabled
What it means
SkipExpressionUtil.checkSkipExpressionVariable throws this FlowableIllegalArgumentException when the value stored under the DynamicBpmnConstants.ENABLE_SKIP_EXPRESSION variable is neither null nor a Boolean. The engine expects the skip-expression toggle to resolve strictly to a boolean.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/SkipExpressionUtil.java:74
String skipExpressionEnabledVariable = "_ACTIVITI_SKIP_EXPRESSION_ENABLED";
Object isSkipExpressionEnabled = execution.getVariable(skipExpressionEnabledVariable);
if (isSkipExpressionEnabled instanceof Boolean) {
return ((Boolean) isSkipExpressionEnabled).booleanValue();
}
skipExpressionEnabledVariable = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
isSkipExpressionEnabled = execution.getVariable(skipExpressionEnabledVariable);
if (isSkipExpressionEnabled == null) {
return false;
} else if (isSkipExpressionEnabled instanceof Boolean) {
return ((Boolean) isSkipExpressionEnabled).booleanValue();
} else {
throw new FlowableIllegalArgumentException("Skip expression variable does not resolve to a boolean. " + isSkipExpressionEnabled);
}
}
public static boolean shouldSkipFlowElement(String skipExpressionString, String activityId, DelegateExecution execution, CommandContext commandContext) {
ExpressionManager expressionManager = CommandContextUtil.getProcessEngineConfiguration(commandContext).getExpressionManager();
Expression skipExpression = expressionManager.createExpression(resolveActiveSkipExpression(skipExpressionString, activityId,
execution.getProcessDefinitionId(), commandContext));
Object value = skipExpression.getValue(execution);
if (value instanceof Boolean) {
return ((Boolean) value).booleanValue();
} else {
throw new FlowableIllegalArgumentException("Skip expression does not resolve to a boolean: " + skipExpression.getExpressionText());
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Set the variable as a Boolean: runtimeService.setVariable(executionId, "_FLOWABLE_SKIP_EXPRESSION_ENABLED", Boolean.TRUE).
- If the value comes from REST/JSON, parse it to Boolean before storing.
- If a String is unavoidable, evaluate it yourself and store the Boolean result, or remove the variable so the null branch (disabled) is used.
- Search dynamic BPMN override JSON for ENABLE_SKIP_EXPRESSION and correct its type to boolean.
Example fix
// before
vars.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", "true");
// after
vars.put("_FLOWABLE_SKIP_EXPRESSION_ENABLED", Boolean.parseBoolean("true")); Defensive patterns
Strategy: validation
Validate before calling
Object v = runtimeService.getVariable(executionId, "_FLOWABLE_SKIP_EXPRESSION_ENABLED");
if (v != null && !(v instanceof Boolean)) {
runtimeService.setVariable(executionId, "_FLOWABLE_SKIP_EXPRESSION_ENABLED",
Boolean.parseBoolean(String.valueOf(v)));
} Type guard
static boolean isSkipToggleValid(Object v) {
return v == null || v instanceof Boolean;
} Try / catch
try {
SkipExpressionUtil.isSkipExpressionEnabled(...);
} catch (FlowableIllegalArgumentException e) {
// treat as disabled and continue
} Prevention
- Always store the skip toggle as java.lang.Boolean.
- Validate types of variables written from REST/scripts before persisting.
- Search dynamic BPMN override JSON for non-boolean ENABLE_SKIP_EXPRESSION values.
When it happens
Trigger: A process- or tenant-level variable (or dynamic BPMN override) named/served via ENABLE_SKIP_EXPRESSION holds a non-Boolean object (String "true", Integer 1, JSON value), and SkipExpressionUtil.isSkipExpressionEnabled evaluates it.
Common situations: Setting the variable via process variables with a String value instead of Boolean; dynamic BPMN overrides serializing values as JsonNode/raw types; scripts or REST calls writing "true"/1 instead of a real boolean; upgrading Flowable where the check became stricter.
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
- Skip expression does not resolve to a boolean: " + skipExpre
- Custom properties resolver delegate expression " + expressio
- Delegate expression " + expression + " did not resolve to an
- Delegate expression " + expression + " did not resolve to an
- Delegate expression " + expression + " did not resolve to an
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2a85ca07e8d4e96d.
Report an issue: GitHub.