{"record":{"id":"48bae7d4aee0ace8","repo":"flowable/flowable-engine","slug":"error-function-nomapper","errorCode":"error.function.nomapper","errorMessage":"error.function.nomapper","messagePattern":"error\\.function\\.nomapper","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/Tree.java","lineNumber":110,"sourceCode":"\t * @param varMapper the variable mapper to use\n\t * @return tree bindings\n\t */\n\tpublic Bindings bind(FunctionMapper fnMapper, VariableMapper varMapper) {\n\t\treturn bind(fnMapper, varMapper, null);\n\t}\n\n\t/**\n\t * Create a bindings.\n\t * @param fnMapper the function mapper to use\n\t * @param varMapper the variable mapper to use\n\t * @param converter custom type converter\n\t * @return tree bindings\n\t */\n\tpublic Bindings bind(FunctionMapper fnMapper, VariableMapper varMapper, TypeConverter converter) {\n\t\tMethod[] methods = null;\n\t\tif (!functions.isEmpty()) {\n\t\t\tif (fnMapper == null) {\n\t\t\t\tthrow new ELException(LocalMessages.get(\"error.function.nomapper\"));\n\t\t\t}\n\t\t\tmethods = new Method[functions.size()];\n\t\t\tfor (int i = 0; i < functions.size(); i++) {\n\t\t\t\tFunctionNode node = functions.get(i);\n\t\t\t\tString image = node.getName();\n\t\t\t\tMethod method = null;\n\t\t\t\tint colon = image.indexOf(':');\n\t\t\t\tif (colon < 0) {\n\t\t\t\t\tmethod = fnMapper.resolveFunction(\"\", image);\n\t\t\t\t} else {\n\t\t\t\t\tmethod = fnMapper.resolveFunction(image.substring(0, colon), image.substring(colon + 1));\n\t\t\t\t}\n\t\t\t\tif (method == null) {\n\t\t\t\t\tthrow new ELException(LocalMessages.get(\"error.function.notfound\", image));\n\t\t\t\t}\n\t\t\t\tif (node.isVarArgs() && method.isVarArgs()) {\n\t\t\t\t\tif (method.getParameterTypes().length > node.getParamCount() + 1) {\n\t\t\t\t\t\tthrow new ELException(LocalMessages.get(\"error.function.params\", image));","sourceCodeStart":92,"sourceCodeEnd":128,"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/Tree.java#L92-L128","documentation":"Tree.bind() found function nodes in the parsed expression tree but the caller passed a null FunctionMapper. Functions cannot be resolved without a mapper, so JUEL throws ELException error.function.nomapper at bind time (i.e. when creating a TreeValueExpression/TreeMethodExpression).","triggerScenarios":"Building a TreeValueExpression/TreeMethodExpression (or calling tree.bind(...)) for an expression containing ${ns:fn(...)} function calls while passing fnMapper == null.","commonSituations":"Evaluating expressions that use custom EL functions in Flowable but constructing the expression without the Flowable function mapper; copying JUEL sample code that omits the FunctionMapper argument; refactoring that dropped the mapper parameter.","solutions":["Pass a FunctionMapper (e.g. Flowable's) that can resolve the functions used in the expression.","Remove unsupported function calls from the expression if no mapper is intended.","Check the expression with a parser/regex for 'prefix:name(' patterns before binding without a mapper.","Catch ELException at bind time and fail fast with a clear configuration message."],"exampleFix":"// before\nnew TreeValueExpression(treeStore, null, varMapper, converter, \"${my:check(x)}\", Boolean.class);\n// after\nnew TreeValueExpression(treeStore, flowableFnMapper, varMapper, converter, \"${my:check(x)}\", Boolean.class);","handlingStrategy":"validation","validationCode":"if (expression.contains(\":\") && expression.matches(\".*\\\\$\\\\{[^}]*[a-zA-Z]+:[a-zA-Z]+\\\\(.*\")) {\n    Objects.requireNonNull(fnMapper, \"Expression uses EL functions but no FunctionMapper was provided\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    expr = new TreeValueExpression(store, fnMapper, varMapper, converter, expression, type);\n} catch (ELException e) {\n    throw new IllegalStateException(\"Expression '\" + expression + \"' needs a FunctionMapper\", e);\n}","preventionTips":["Always pass the platform's FunctionMapper when expressions may contain functions.","Grep expressions for prefix:name( patterns before binding without a mapper.","Centralize expression construction so the mapper is never omitted.","Fail fast at startup with a check that the mapper is configured."],"tags":["el","function-mapper","expression-binding"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}