{"record":{"id":"2635c79951d59f0d","repo":"flowable/flowable-engine","slug":"condition-expression-returns-non-boolean-elementi","errorCode":null,"errorMessage":"condition expression returns non-Boolean (elementId: \" + elementId + \"): \" + result + \" (\" + result.getClass().getName() + \") for \" + execution","messagePattern":"condition expression returns non-Boolean \\(elementId: \" \\+ elementId \\+ \"\\): \" \\+ result \\+ \" \\(\" \\+ result\\.getClass\\(\\)\\.getName\\(\\) \\+ \"\\) for \" \\+ execution","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/el/UelExpressionCondition.java","lineNumber":43,"sourceCode":" * @author Frederik Heremans\n */\npublic class UelExpressionCondition implements Condition {\n\n    protected Expression expression;\n\n    public UelExpressionCondition(Expression expression) {\n        this.expression = expression;\n    }\n\n    @Override\n    public boolean evaluate(String elementId, DelegateExecution execution) {\n        Object result = expression.getValue(execution);\n\n        if (result == null) {\n            throw new FlowableException(\"condition expression returns null (elementId: \" + elementId + \") for \" + execution);\n        }\n        if (!(result instanceof Boolean)) {\n            throw new FlowableException(\"condition expression returns non-Boolean (elementId: \" + elementId + \"): \" + result + \" (\" + result.getClass().getName() + \") for \" + execution);\n        }\n        return (Boolean) result;\n    }\n\n}\n","sourceCodeStart":25,"sourceCodeEnd":49,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/el/UelExpressionCondition.java#L25-L49","documentation":"Thrown by UelExpressionCondition.evaluate when a condition expression evaluates to a non-Boolean value. BPMN conditional flows require a strict Boolean result; any other type (String, Integer, etc.) cannot be used to decide the branch, so the engine throws and includes the actual value and its class name.","triggerScenarios":"evaluate(elementId, execution) where expression.getValue(execution) returns a non-Boolean, e.g. conditionExpression '${approved}' where variable approved is a String \"true\" instead of boolean, or an expression like ${count} resolving to an Integer, or an EL method returning a non-boolean type.","commonSituations":"Variables set as Strings from JSON/forms but used directly in conditions; expressions like ${var == 'x'} accidentally written as ${var} with a String value; returning wrong type from a bean method; languages/data sources where booleans serialize as 'true'/'false' strings.","solutions":["Convert the value to a real Boolean: set the variable as java.lang.Boolean instead of String.","Make the expression return a Boolean, e.g. ${approved == 'true'} or ${Boolean.parseBoolean(approved)} instead of ${approved}.","Read the class name in the message to identify the offending type, then fix the variable set on the execution.","If the value comes from a form/API, normalize it to boolean before passing to startProcessInstance or setVariable."],"exampleFix":"// before\nvars.put(\"approved\", \"true\"); // String\n// after\nvars.put(\"approved\", Boolean.TRUE);","handlingStrategy":"type-guard","validationCode":"Object approved = vars.get(\"approved\");\nif (!(approved instanceof Boolean)) {\n    throw new IllegalArgumentException(\"approved must be Boolean, got \" + (approved == null ? null : approved.getClass()));\n}","typeGuard":"boolean isBoolVar(Map<String, Object> vars, String name) {\n    return vars.get(name) instanceof Boolean;\n}","tryCatchPattern":"try {\n    runtimeService.startProcessInstanceByKey(key, vars);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"condition expression returns non-Boolean\")) {\n        // normalize the variable type named in the message and retry\n    }\n}","preventionTips":["Store booleans as Boolean, never as \"true\"/\"false\" Strings.","Keep condition expressions strictly Boolean-producing.","Validate form/API payloads for boolean-typed variables before submission.","Add deployment-time checks or tests that evaluate each conditionExpression with sample variables."],"tags":["bpmn","expression-language","type-mismatch","process-engine"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}