flowable/flowable-engine · error · TreeBuilderException
e.getMessage()
Error message
e.getMessage()
What it means
TreeBuilderImpl.build() parses an expression and, on ScanException or ParseException, rethrows it as a TreeBuilderException carrying the expression, error position, encountered text, expected tokens, and e.getMessage() as the detail message. It is the parse-failure path of the EL compiler — the expression string is syntactically invalid.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/Builder.java:108
}
}
/**
* @return <code>true</code> iff the specified feature is supported.
*/
public boolean isEnabled(Feature feature) {
return features.contains(feature);
}
/**
* Parse expression.
*/
@Override
public Tree build(String expression) throws TreeBuilderException {
try {
return createParser(expression).tree();
} catch (ScanException e) {
throw new TreeBuilderException(expression, e.position, e.encountered, e.expected, e.getMessage());
} catch (ParseException e) {
throw new TreeBuilderException(expression, e.position, e.encountered, e.expected, e.getMessage());
}
}
protected Parser createParser(String expression) {
return new Parser(this, expression);
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
return features.equals(((Builder)obj).features);
}
@OverrideView on GitHub (pinned to d6d39ce1c6)
Solutions
- Fix the expression syntax at the reported position (the exception exposes position, encountered, and expected).
- Escape or remove characters not allowed by the EL grammar (quotes, '${' without matching '}').
- Validate expressions at deploy/build time using a TreeBuilder parse pass instead of at runtime.
- Catch TreeBuilderException and log expression + position to locate the offending definition quickly.
Example fix
// before
String expr = "${user.name " ; // unbalanced -> TreeBuilderException
// after
String expr = "${user.name}"; // or pre-validate:
try { treeBuilder.build(expr); } catch (TreeBuilderException e) {
throw new IllegalArgumentException("Bad EL at " + e.getPosition() + ": " + expr);
} Defensive patterns
Strategy: validation
Validate before calling
// pre-validate an expression before using it at runtime
try {
new TreeBuilderImpl(new Builder()).build(expression);
} catch (TreeBuilderException e) {
throw new IllegalArgumentException("Invalid EL at pos " + e.getPosition()
+ ", encountered '" + e.getEncountered() + "', expected " + e.getExpected());
} Try / catch
try {
Tree tree = treeBuilder.build(expression);
} catch (TreeBuilderException e) {
log.error("EL parse error in '{}' at pos {}: encountered '{}' expected {}",
e.getExpression(), e.getPosition(), e.getEncountered(), e.getExpected());
throw new IllegalArgumentException("Malformed expression", e);
} Prevention
- Validate all expressions at deploy/build time with a parse dry run.
- Escape '${' when emitting literal text and balance braces when composing expressions dynamically.
- Sanitize user input before embedding it into expression strings.
- Include position/expected-token info in your error reports to speed up fixes.
When it happens
Trigger: build(expression) is invoked with a syntactically invalid EL string, e.g. unbalanced '${', bad escape sequences, or illegal token sequences, and the underlying parser throws ScanException/ParseException.
Common situations: Process definitions or templates containing broken expressions (missing '}', stray quotes); dynamically composed expressions where variable interpolation produced invalid EL; expressions containing characters the scanner does not accept (locale text, newlines).
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
- ' + token.getImage() + '
- Illegal characters for this position: '
- Illegal character after ?:
- Error while reading the BPMN 2.0 XML
- <exception message from evaluation failure>
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c2de9bc083b5f806.
Report an issue: GitHub.