{"record":{"id":"41a7c4f887b0769e","repo":"flowable/flowable-engine","slug":"error-function-params","errorCode":"error.function.params","errorMessage":"error.function.params","messagePattern":"error\\.function\\.params","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":128,"sourceCode":"\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));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (method.getParameterTypes().length != node.getParamCount()) {\n\t\t\t\t\t\tthrow new ELException(LocalMessages.get(\"error.function.params\", image));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmethods[node.getIndex()] = method;\n\t\t\t}\n\t\t}\n\t\tValueExpression[] expressions = null;\n\t\tif (identifiers.size() > 0) {\n\t\t\texpressions = new ValueExpression[identifiers.size()];\n\t\t\tfor (int i = 0; i < identifiers.size(); i++) {\n\t\t\t\tIdentifierNode node = identifiers.get(i);\n\t\t\t\tValueExpression expression = null;\n\t\t\t\tif (varMapper != null) {\n\t\t\t\t\texpression = varMapper.resolveVariable(node.getName());\n\t\t\t\t}","sourceCodeStart":110,"sourceCodeEnd":146,"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#L110-L146","documentation":"Tree.bind() resolved the function Method but its arity does not match the parsed call: for varargs functions the method may take at most paramCount+1 parameters, otherwise it must take exactly paramCount. JUEL throws ELException error.function.params naming the function image.","triggerScenarios":"Expression calls ns:fn(a, b) but the resolved Method (a) has no varargs and a different number of parameters than the call, or (b) is varargs with more declared parameters than call args + 1.","commonSituations":"A registered function's signature was changed (parameters added/removed) while expressions in process definitions still use the old arity; overloading confusion where resolveFunction picked a wrong overload; copy-pasted expressions reused with a different function of the same name.","solutions":["Update the expression to pass the number of arguments the registered Method expects.","Change the registered Method (or add an overload) to match the arity used in expressions; prefer a varargs signature for flexible arity.","Re-scan deployed process definitions for function calls after changing function signatures.","Catch ELException and validate function arity in a startup test suite."],"exampleFix":"// before\n// method: sum(int a, int b); expression: ${math:sum(1, 2, 3)} -> error.function.params\n// after\npublic static int sum(int... values) { ... } // or fix the expression to ${math:sum(1, 2)}","handlingStrategy":"validation","validationCode":"Method m = fnMapper.resolveFunction(prefix, localName);\nif (m != null && argCount != m.getParameterCount()\n    && !(m.isVarArgs() && m.getParameterCount() <= argCount + 1)) {\n    throw new IllegalStateException(fn + \" expects \" + m.getParameterCount() + \" args, got \" + argCount);\n}","typeGuard":null,"tryCatchPattern":"try {\n    bindings = tree.bind(fnMapper, varMapper, converter);\n} catch (ELException e) {\n    throw new ConfigurationException(\"Function signature mismatch: \" + e.getMessage(), e);\n}","preventionTips":["Keep function signatures stable; deprecate before changing parameter counts.","Prefer varargs methods for functions with optional arguments.","Run a deploy-time pass that binds all expressions to catch arity errors early.","Version function namespaces when signatures change."],"tags":["el","function-signature","arity-mismatch"],"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"}