flowable/flowable-engine · error · UnsupportedOperationException

Lambda parameters marker should not be evaluated

Error message

Lambda parameters marker should not be evaluated

What it means

The Parser defines an internal AST node representing the '|' lambda-parameter marker used only during parsing. Its eval() is deliberately unimplemented: this marker is a parse-time construct and must never be part of a tree that gets evaluated. Throwing UnsupportedOperationException here is an internal-invariant guard, not a condition a user is expected to trigger through normal API use.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/Parser.java:341

		public List<String> getParameterNames() {
			return parameterNames;
		}

		@Override
		public void appendStructure(StringBuilder builder, Bindings bindings) {
			builder.append("(");
			for (int i = 0; i < parameterNames.size(); i++) {
				if (i > 0)
					builder.append(", ");
				builder.append(parameterNames.get(i));
			}
			builder.append(")");
		}

		@Override
		public Object eval(Bindings bindings, ELContext context) {
			throw new UnsupportedOperationException("Lambda parameters marker should not be evaluated");
		}

		@Override
		public boolean isLiteralText() {
			return false;
		}

		@Override
		public boolean isLeftValue() {
			return false;
		}

		@Override
		public boolean isMethodInvocation() {
			return false;
		}

		@Override

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Do not evaluate parser-internal AST nodes; always obtain the finished Tree via Parser.tree()/Builder.build() and evaluate from the root AstNode.
  2. Check for custom code extending Parser or reusing its anonymous inner classes and refactor to the public API.
  3. If you fork the library, guard evaluation so the marker node is replaced during tree construction instead of surviving into the evaluated tree.

Example fix

// before
Object v = parserNode.eval(bindings, context); // evaluates marker node
// after
Tree tree = builder.build(expression);
Object v = tree.getRoot().eval(bindings, context);
Defensive patterns

Strategy: type-guard

Validate before calling

// only evaluate finished trees obtained from Builder.build(); reject raw parser nodes
if (node.getClass().getName().contains("Parser$")) throw new IllegalStateException("internal AST node");

Type guard

boolean isEvaluatable(Object node) { return node instanceof AstNode && !node.getClass().isSynthetic() && !node.getClass().getName().contains("Parser$"); }

Try / catch

try {
    return node.eval(bindings, context);
} catch (UnsupportedOperationException e) {
    throw new IllegalStateException("Attempted to evaluate parser-internal AST node", e);
}

Prevention

When it happens

Trigger: Evaluating an AST that still contains the lambda-parameters marker node — i.e. calling eval on a partially built or raw Parser inner node rather than a completed Tree, typically from custom code that reaches into Parser internals.

Common situations: Custom subclasses or forks of the Odysseus EL parser that reuse the parser's inner AST classes directly; reflection-based tooling that walks parser internals; framework upgrades that changed tree construction.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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