{"record":{"id":"aa52737ee0ede427","repo":"flowable/flowable-engine","slug":"cannot-invoke-method","errorCode":null,"errorMessage":"Cannot invoke method ","messagePattern":"Cannot invoke method ","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/util/RootPropertyResolver.java","lineNumber":105,"sourceCode":"\tpublic boolean isReadOnly(ELContext context, Object base, Object property) {\n\t\treturn resolve(context, base, property) ? readOnly : false;\n\t}\n\n\t@Override\n\tpublic void setValue(ELContext context, Object base, Object property, Object value)\n\t\t\tthrows PropertyNotWritableException {\n\t\tif (resolve(context, base, property)) {\n\t\t\tif (readOnly) {\n\t\t\t\tthrow new PropertyNotWritableException(\"Resolver is read only!\");\n\t\t\t}\n\t\t\tsetProperty((String) property, value);\n\t\t}\n\t}\n\n\t@Override\n\tpublic Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {\n\t\tif (resolve(context, base, method)) {\n\t\t\tthrow new NullPointerException(\"Cannot invoke method \" + method + \" on null\");\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get property value\n\t * \n\t * @param property\n\t *            property name\n\t * @return value associated with the given property\n\t */\n\tpublic Object getProperty(String property) {\n\t\treturn map.get(property);\n\t}\n\n\t/**\n\t * Set property value\n\t * ","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/util/RootPropertyResolver.java#L87-L123","documentation":"RootPropertyResolver.invoke resolves the (base, method) pair and, if it matches the root, throws NullPointerException 'Cannot invoke method <m> on null' because the resolver holds no invocable object for the method. It signals that method dispatch is unsupported on this root resolver.","triggerScenarios":"Evaluating an EL method call like '${root.someMethod()}' where base is the root object managed by RootPropertyResolver and no such method exists/is invocable on the root.","commonSituations":"Expressions calling helper methods that were never exposed on the root object; expecting the root resolver to behave like a bean resolver; renamed methods after refactoring.","solutions":["Expose the method on the actual root object or switch to a BeanNameResolver/ELResolver that supports method invocation.","Replace the method call with a precomputed property: set the result via setProperty and reference the property in the expression.","Verify the method name against the root object's public methods before evaluating."],"exampleFix":"// before\nresolver.invoke(ctx, root, \"formatDate\", null, null); // NPE\n// after\nresolver.setProperty(\"formattedDate\", formatter.format(date));\nel.eval(\"${formattedDate}\");","handlingStrategy":"validation","validationCode":"Method m = root.getClass().getMethod(methodName); if (m == null) throw new IllegalArgumentException(\"Method not invocable on root: \" + methodName);","typeGuard":null,"tryCatchPattern":"try { resolver.invoke(ctx, root, method, null, null); } catch (NullPointerException | ELException e) { log.error(\"Cannot invoke {} on root resolver\", method); }","preventionTips":["Only call methods exposed on real bean resolvers, not the root property resolver","Precompute method results into properties before evaluation","Keep root object method names in sync with expressions via tests"],"tags":["el","resolver","method-invocation","null"],"backgroundTag":"unsupported-operation","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"}