{"record":{"id":"31eab654bdd78587","repo":"flowable/flowable-engine","slug":"lambda-parameters-marker-should-not-be-evaluated","errorCode":null,"errorMessage":"Lambda parameters marker should not be evaluated","messagePattern":"Lambda parameters marker should not be evaluated","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/Parser.java","lineNumber":341,"sourceCode":"\n\t\tpublic List<String> getParameterNames() {\n\t\t\treturn parameterNames;\n\t\t}\n\n\t\t@Override\n\t\tpublic void appendStructure(StringBuilder builder, Bindings bindings) {\n\t\t\tbuilder.append(\"(\");\n\t\t\tfor (int i = 0; i < parameterNames.size(); i++) {\n\t\t\t\tif (i > 0)\n\t\t\t\t\tbuilder.append(\", \");\n\t\t\t\tbuilder.append(parameterNames.get(i));\n\t\t\t}\n\t\t\tbuilder.append(\")\");\n\t\t}\n\n\t\t@Override\n\t\tpublic Object eval(Bindings bindings, ELContext context) {\n\t\t\tthrow new UnsupportedOperationException(\"Lambda parameters marker should not be evaluated\");\n\t\t}\n\n\t\t@Override\n\t\tpublic boolean isLiteralText() {\n\t\t\treturn false;\n\t\t}\n\n\t\t@Override\n\t\tpublic boolean isLeftValue() {\n\t\t\treturn false;\n\t\t}\n\n\t\t@Override\n\t\tpublic boolean isMethodInvocation() {\n\t\t\treturn false;\n\t\t}\n\n\t\t@Override","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/Parser.java#L323-L359","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Do not evaluate parser-internal AST nodes; always obtain the finished Tree via Parser.tree()/Builder.build() and evaluate from the root AstNode.","Check for custom code extending Parser or reusing its anonymous inner classes and refactor to the public API.","If you fork the library, guard evaluation so the marker node is replaced during tree construction instead of surviving into the evaluated tree."],"exampleFix":"// before\nObject v = parserNode.eval(bindings, context); // evaluates marker node\n// after\nTree tree = builder.build(expression);\nObject v = tree.getRoot().eval(bindings, context);","handlingStrategy":"type-guard","validationCode":"// only evaluate finished trees obtained from Builder.build(); reject raw parser nodes\nif (node.getClass().getName().contains(\"Parser$\")) throw new IllegalStateException(\"internal AST node\");","typeGuard":"boolean isEvaluatable(Object node) { return node instanceof AstNode && !node.getClass().isSynthetic() && !node.getClass().getName().contains(\"Parser$\"); }","tryCatchPattern":"try {\n    return node.eval(bindings, context);\n} catch (UnsupportedOperationException e) {\n    throw new IllegalStateException(\"Attempted to evaluate parser-internal AST node\", e);\n}","preventionTips":["Never evaluate Parser inner classes directly; go through Tree.getRoot().eval().","Avoid forking parser internals; extend via public APIs only.","Pin the library version and review upstream changes before upgrading.","Add an assertion in custom tooling that trees come from Builder.build()."],"tags":["el","unsupported-operation","internal-invariant","lambda"],"backgroundTag":"internal-invariant-violation","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"}