flowable/flowable-engine · error · ELException

error.coerce.value

error.coerce.value

Error message

error.coerce.value

What it means

Thrown when a String value cannot be parsed as a BigDecimal during EL coercion in TypeConverterImpl.coerceToBigDecimal. The code catches NumberFormatException from new BigDecimal(String) and rethrows it as ELException with code error.coerce.value. Unlike error.coerce.type, the type was correct but the value's content was invalid.

Solutions

  1. Sanitize the string before it reaches EL: strip currency symbols, grouping separators, and whitespace.
  2. Normalize to the expected decimal format: replace ',' with '.' for decimal separators and remove thousands separators.
  3. Parse/validate with new BigDecimal(str) in a try-catch in your own code before evaluating the expression.
  4. Fix the source data so numeric fields contain only valid numeric text.

Example fix

// before
String amount = "€1,234.56"; // used in ${amount * 2}
// after
String amount = new BigDecimal("1,234.56".replace("€","").replace(",","")).toString(); // "1234.56"
Defensive patterns

Strategy: validation

Validate before calling

try { new java.math.BigDecimal(str.trim().replace(",", "")); return true; } catch (NumberFormatException e) { return false; }

Type guard

static boolean isBigDecimalParsable(String s) { try { new java.math.BigDecimal(s.trim()); return true; } catch (Exception e) { return false; } }

Try / catch

try { Object r = expression.getValue(context); } catch (jakarta.el.ELException e) { if (e.getCause() instanceof NumberFormatException nfe) { log.error("Invalid numeric string: {}", nfe.getMessage()); } }

Prevention

When it happens

Trigger: An EL expression produces a String like "12.3abc", "", locale-formatted numbers ("1,234.56" with grouped separators or comma decimals), currency symbols, or trailing whitespace where a BigDecimal operand is required (arithmetic, comparisons, numeric assignment).

Common situations: User-supplied input bound into EL variables; locale differences (German "1.234,56" parsed as "1.234"); currency/percentage strings from forms; whitespace or non-breaking spaces from spreadsheets.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/misc/TypeConverterImpl.java:88

	protected BigDecimal coerceToBigDecimal(Object value) {
		if (value == null || "".equals(value)) {
			return BigDecimal.valueOf(0L);
		}
		if (value instanceof BigDecimal) {
			return (BigDecimal)value;
		}
		if (value instanceof BigInteger) {
			return new BigDecimal((BigInteger)value);
		}
		if (value instanceof Number) {
			return new BigDecimal(((Number)value).doubleValue());
		}
		if (value instanceof String) {
			try {
				return new BigDecimal((String)value);
			} catch (NumberFormatException e) {
				throw new ELException(LocalMessages.get("error.coerce.value", value, value.getClass(), BigDecimal.class), e);
			}
		}
		if (value instanceof Character) {
			return new BigDecimal((short)((Character)value).charValue());
		}
        if (value instanceof LambdaExpression lambdaExpression) {
            return coerceToBigDecimal(resolveLambdaExpression(lambdaExpression));
        }
		throw new ELException(LocalMessages.get("error.coerce.type", value, value.getClass(), BigDecimal.class));
	}

	protected BigInteger coerceToBigInteger(Object value) {
		if (value == null || "".equals(value)) {
			return BigInteger.valueOf(0L);
		}
		if (value instanceof BigInteger) {
			return (BigInteger)value;
		}

View on GitHub (pinned to d6d39ce1c6)