{"record":{"id":"7622cd7a8ea5c6f1","repo":"flowable/flowable-engine","slug":"error-coerce-type","errorCode":"error.coerce.type","errorMessage":"error.coerce.type","messagePattern":"error\\.coerce\\.type","errorType":"exception","errorClass":"ELException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/misc/TypeConverterImpl.java","lineNumber":49,"sourceCode":" * Type Conversions as described in EL 2.1 specification (section 1.17).\n */\npublic class TypeConverterImpl implements TypeConverter {\n\tprivate static final long serialVersionUID = 1L;\n\n\tprotected Boolean coerceToBoolean(Object value) {\n\t\tif (value == null || \"\".equals(value)) {\n\t\t\treturn Boolean.FALSE;\n\t\t}\n\t\tif (value instanceof Boolean) {\n\t\t\treturn (Boolean)value;\n\t\t}\n\t\tif (value instanceof String) {\n\t\t\treturn Boolean.valueOf((String)value);\n\t\t}\n        if (value instanceof LambdaExpression lambdaExpression) {\n            return coerceToBoolean(resolveLambdaExpression(lambdaExpression));\n        }\n\t\tthrow new ELException(LocalMessages.get(\"error.coerce.type\", value, value.getClass(), Boolean.class));\n\t}\n\n\tprotected Character coerceToCharacter(Object value) {\n\t\tif (value == null || \"\".equals(value)) {\n\t\t\treturn Character.valueOf((char)0);\n\t\t}\n\t\tif (value instanceof Character) {\n\t\t\treturn (Character)value;\n\t\t}\n\t\tif (value instanceof Number) {\n\t\t\treturn Character.valueOf((char)((Number)value).shortValue());\n\t\t}\n\t\tif (value instanceof String) {\n\t\t\treturn Character.valueOf(((String)value).charAt(0));\n\t\t}\n        if (value instanceof LambdaExpression lambdaExpression) {\n            return coerceToCharacter(resolveLambdaExpression(lambdaExpression));\n        }","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/misc/TypeConverterImpl.java#L31-L67","documentation":"This error is thrown by the Flowable-bundled Odysseus EL TypeConverterImpl when a value cannot be coerced to Boolean. The coercion path accepts null/empty (false), Boolean, String, and LambdaExpression (resolved and retried); any other object type reaches the final throw and triggers error.coerce.type. It is wrapped in jakarta/javax ELException.","triggerScenarios":"An EL expression evaluates to a non-String, non-Boolean object (e.g. a Number, Date, or POJO) where a boolean result is required, such as in an ${...} condition used by a Flowable condition expression, delegate, or JSP-style EL evaluation.","commonSituations":"Condition expressions on sequence flows returning numeric IDs instead of booleans; beans returning wrapper objects; version upgrades (Java 17 pattern matching variant) where a resolver now yields a typed object instead of a String.","solutions":["Fix the EL expression or bean so it evaluates to a Boolean or String parsable by Boolean.valueOf (e.g. ${order.approved} instead of ${order.status}).","Convert the value in your bean/delegate before returning (e.g. return \"true\"/\"false\" or Boolean).","Catch ELException in your expression-evaluation call site and log the offending expression/value.","If using a custom ELResolver, ensure it only resolves values of types the converter supports."],"exampleFix":"// before\n<conditionExpression>${order.status}</conditionExpression>\n// after\n<conditionExpression>${order.status == 'APPROVED'}</conditionExpression>","handlingStrategy":"type-guard","validationCode":"boolean valid = value == null || value instanceof Boolean || value instanceof String || value instanceof Number;","typeGuard":"static boolean isBooleanCoercible(Object v) { return v == null || v instanceof Boolean || v instanceof String || v instanceof org.flowable.common.engine.impl.de.odysseus.el.tree.impl.ast.LambdaExpression; }","tryCatchPattern":"try { Object r = expression.getValue(context); } catch (jakarta.el.ELException e) { log.error(\"EL boolean coercion failed: {}\", e.getMessage()); }","preventionTips":["Make condition expressions explicitly boolean comparisons (==, >, isEmpty()).","Return Boolean from bean getters used in EL conditions.","Never feed raw numeric IDs or enums directly as boolean conditions.","Unit-test EL expressions with representative bean values."],"tags":["el","type-coercion","flowable","expression-language"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}