flowable/flowable-engine · error · FlowableException
condition script returns non-Boolean: () for
Error message
condition script returns non-Boolean: () for
What it means
FlowableException thrown by ScriptCondition.evaluate when a condition script returns a value that is not a java.lang.Boolean. Flowable gateway routing requires a strict Boolean; any other type (String 'true', Integer, etc.) is rejected, with the actual value and its class included in the message.
Solutions
- End the condition script with an explicit boolean comparison, e.g. return approved == 'true' or return count > 0.
- Convert string variables before use: Boolean.parseBoolean(approved) in the script or store variables as Boolean from the start.
- If using EL expressions (not scripts), wrap in a comparison: ${approved == true} instead of ${approved}.
Example fix
// before (groovy) return approved // after return Boolean.TRUE.equals(approved) || 'true'.equals(approved)
Defensive patterns
Strategy: validation
Validate before calling
Object flag = execution.getVariable("approved");
if (!(flag instanceof Boolean)) {
execution.setVariable("approved", Boolean.parseBoolean(String.valueOf(flag)));
} Type guard
boolean isBooleanResult(Object o) {
return o instanceof Boolean;
} Try / catch
try {
return (Boolean) scriptingEngines.evaluate(request).getResult();
} catch (FlowableException e) {
log.error("non-boolean condition result: {}", e.getMessage());
throw e;
} Prevention
- Store boolean process variables as java.lang.Boolean, not String 'true'
- End condition scripts with an explicit comparison (x > 0, == 'true')
- Prefer EL expressions with explicit comparisons over bare variables
- Cover each condition with a script unit test asserting a Boolean result
When it happens
Trigger: A condition script (e.g. groovy returning 'true' as String, or javascript returning 1/0, or returning a java.lang.String from EL ${var} where var is a String) evaluates to a non-Boolean result for a conditional flow.
Common situations: Variables stored as String 'true'/'false' used directly as conditions; JS engine coercing to numbers; scripts returning status codes or objects instead of a boolean comparison; language confusion between expression vs script conditions.
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
- condition script returns non-Boolean
- condition script returns null: for
- App resource is not of type AppModel
- Can only move a history job to a history job
- Can only use a collection of String elements for…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/6318d0c30159c4e5.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/scripting/ScriptCondition.java:48
public ScriptCondition(String expression, String language) {
this.expression = expression;
this.language = language;
}
@Override
public boolean evaluate(String elementId, DelegateExecution execution) {
ScriptingEngines scriptingEngines = CommandContextUtil.getProcessEngineConfiguration().getScriptingEngines();
ScriptEngineRequest.Builder builder = ScriptEngineRequest.builder()
.script(expression)
.language(language)
.scopeContainer(execution);
Object result = scriptingEngines.evaluate(builder.build()).getResult();
if (result == null) {
throw new FlowableException("condition script returns null: " + expression + " for " + execution);
}
if (!(result instanceof Boolean)) {
throw new FlowableException("condition script returns non-Boolean: " + result + " (" + result.getClass().getName() + ") for " + execution);
}
return (Boolean) result;
}
}
View on GitHub (pinned to d6d39ce1c6)