{"record":{"id":"597d1c5b76304551","repo":"flowable/flowable-engine","slug":"expected-lambdaexpression-but-got-lambdaobj","errorCode":null,"errorMessage":"Expected LambdaExpression but got: \" + (lambdaObj == null ? \"null\" : lambdaObj.getClass().getName())","messagePattern":"Expected LambdaExpression but got: \" \\+ \\(lambdaObj == null \\? \"null\" : lambdaObj\\.getClass\\(\\)\\.getName\\(\\)\\)","errorType":"exception","errorClass":"ELException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstLambdaInvocation.java","lineNumber":46,"sourceCode":"\n    public AstLambdaInvocation(AstNode lambdaNode, AstParameters params) {\n        this.lambdaNode = lambdaNode;\n        this.params = params;\n    }\n\n    @Override\n    public void appendStructure(StringBuilder builder, Bindings bindings) {\n        lambdaNode.appendStructure(builder, bindings);\n        params.appendStructure(builder, bindings);\n    }\n\n    @Override\n    public Object eval(Bindings bindings, ELContext context) {\n        // Evaluate the lambda expression\n        Object lambdaObj = lambdaNode.eval(bindings, context);\n\n        if (!(lambdaObj instanceof LambdaExpression)) {\n            throw new ELException(\"Expected LambdaExpression but got: \" +\n                (lambdaObj == null ? \"null\" : lambdaObj.getClass().getName()));\n        }\n\n        LambdaExpression lambda = (LambdaExpression) lambdaObj;\n\n        // Evaluate the arguments\n        Object[] args = params.eval(bindings, context);\n\n        // Invoke the lambda\n        Object result = lambda.invoke(context, args);\n        return result;\n    }\n\n    @Override\n    public int getCardinality() {\n        return 2;\n    }\n","sourceCodeStart":28,"sourceCodeEnd":64,"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/ast/AstLambdaInvocation.java#L28-L64","documentation":"AstLambdaInvocation.eval evaluates the expression being invoked and requires it to be a LambdaExpression instance. If the evaluated target is null or any other type, it throws ELException describing the actual type. This means the code invoked something as a lambda function that did not evaluate to a lambda.","triggerScenarios":"Writing ${someIdentifier(args)} where someIdentifier evaluates to null or a non-lambda value (String, number, bean) instead of a lambda defined like (x -> x*2)(5); referencing a lambda variable before it is bound.","commonSituations":"Typos in lambda variable names; lambda defined in a different scope than the invocation; passing a non-lambda value into a position the caller treats as a function; null process variables used as functions.","solutions":["Verify the invoked identifier is defined as a lambda, e.g. define it via the ELContext VariableMapper or a surrounding lambda expression.","Null-check the variable before invocation: ${not empty f ? f(x) : ''}.","Correct typos/scoping so the lambda variable is visible at the invocation site.","Log/bind the value to confirm its runtime type before invoking it."],"exampleFix":"// before\n${myFuntion(42)}  // typo, resolves to null\n// after\n${myFunction(42)} // where myFunction := x -> x + 1","handlingStrategy":"type-guard","validationCode":"Object f = factory.createValueExpression(ctx, \"${fn}\", Object.class).getValue(context);\nif (f == null) throw new IllegalStateException(\"Lambda variable 'fn' is not bound\");","typeGuard":"boolean isLambda(Object v) { return v instanceof LambdaExpression; }","tryCatchPattern":"try {\n    return lambdaInvocationExpr.getValue(context);\n} catch (ELException e) {\n    if (!e.getMessage().startsWith(\"Expected LambdaExpression\")) throw e;\n    return null; // or fallback invocation path\n}","preventionTips":["Null-check function variables before invoking them in EL","Define lambdas before/above their invocation scope","Log the runtime type of dynamic call targets during development"],"tags":["el","expression-language","lambda","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}