{"record":{"id":"676e6df57b2c3d9b","repo":"flowable/flowable-engine","slug":"error-identifier-method-invocation","errorCode":null,"errorMessage":"error.identifier.method.invocation","messagePattern":"error\\.identifier\\.method\\.invocation","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/AstIdentifier.java","lineNumber":183,"sourceCode":"\t\t\t\tpublic String getExpressionString() {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\t@Override\n\t\t\t\tpublic int hashCode() {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\t@Override\n\t\t\t\tpublic boolean equals(Object obj) {\n\t\t\t\t\treturn obj == this;\n\t\t\t\t}\n\t\t\t\t@Override\n\t\t\t\tpublic Object invoke(ELContext context, Object[] params) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn method.invoke(null, params);\n\t\t\t\t\t} catch (IllegalAccessException e) {\n\t\t\t\t\t\tthrow new ELException(LocalMessages.get(\"error.identifier.method.access\", name), e);\n\t\t\t\t\t} catch (IllegalArgumentException e) {\n\t\t\t\t\t\tthrow new ELException(LocalMessages.get(\"error.identifier.method.invocation\", name, e));\n\t\t\t\t\t} catch (InvocationTargetException e) {\n\t\t\t\t\t\tthrow new ELException(LocalMessages.get(\"error.identifier.method.invocation\", name, e.getCause()));\n\t\t\t\t\t}\n\t\t\t\t}\t\t\t\n\t\t\t\t@Override\n\t\t\t\tpublic MethodInfo getMethodInfo(ELContext context) {\n\t\t\t\t\treturn new MethodInfo(method.getName(), method.getReturnType(), method.getParameterTypes());\n\t\t\t\t}\n\t\t\t};\n\t\t} else if (value instanceof MethodExpression) {\n\t\t\treturn (MethodExpression)value;\n\t\t}\n\t\tthrow new MethodNotFoundException(LocalMessages.get(\"error.identifier.method.notamethod\", name, value.getClass()));\n\t}\n\n\t@Override\n\tpublic MethodInfo getMethodInfo(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes) {\n\t\treturn getMethodExpression(bindings, context, returnType, paramTypes).getMethodInfo(context);","sourceCodeStart":165,"sourceCodeEnd":201,"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/AstIdentifier.java#L165-L201","documentation":"Wraps java.lang.IllegalArgumentException raised during method.invoke(null, params) — the supplied arguments do not match the method's declared parameter types, or the method is not static/invoked with wrong receiver. The reflective invocation itself failed on argument binding. Note the message includes the exception, whereas the InvocationTargetException branch unwraps the cause.","triggerScenarios":"Invoking a method expression with params whose runtime types (or count) do not match the Method's parameter types; passing null where a primitive is expected; invoking an instance method as static.","commonSituations":"EL expression passes a String where the delegate expects an Integer; flowable passes a DelegateExecution but the method expects a different type; primitive parameters receiving null argument values from variables.","solutions":["Match argument types to the method signature (convert numerics/strings explicitly)","Avoid nulls for primitive parameters (use wrapper parameter types or provide defaults)","Ensure the resolved Method is static when invoked with a null receiver","Log/print paramTypes vs the method's getParameterTypes() to spot mismatches"],"exampleFix":"// before: expression ${calc(orders)} where orders is String \"5\" and calc(int)\n// after: set the variable as Integer\nexecution.setVariable(\"orders\", Integer.parseInt(orderCountString));","handlingStrategy":"validation","validationCode":"Object[] args = ...;\nClass<?>[] declared = method.getParameterTypes();\nif (args.length != declared.length) throw new IllegalArgumentException(\"Arg count mismatch for \" + method);\nfor (int i = 0; i < declared.length; i++) {\n  if (args[i] == null && declared[i].isPrimitive()) throw new IllegalArgumentException(\"Null for primitive param \" + i);\n}","typeGuard":"boolean argsCompatible(Object[] args, Class<?>[] types) {\n  if (args.length != types.length) return false;\n  for (int i = 0; i < types.length; i++) {\n    if (args[i] == null ? types[i].isPrimitive() : !types[i].isInstance(args[i])) return false;\n  }\n  return true;\n}","tryCatchPattern":"try {\n  methodExpr.invoke(context, params);\n} catch (ELException e) {\n  if (e.getCause() instanceof IllegalArgumentException) {\n    logger.error(\"Argument type mismatch invoking EL method: {}\", e.getMessage());\n  }\n  throw e;\n}","preventionTips":["Convert variables to the exact types the method declares before evaluation","Use wrapper types instead of primitives for nullable EL parameters","Validate variable types with unit tests that run real expressions","Document expected parameter types on EL-exposed methods"],"tags":["reflection","argument-mismatch","el","flowable"],"backgroundTag":"invalid-argument-value","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"}