{"record":{"id":"0fe173e82d9f2be8","repo":"flowable/flowable-engine","slug":"error-property-method-notfound","errorCode":null,"errorMessage":"error.property.method.notfound","messagePattern":"error\\.property\\.method\\.notfound","errorType":"exception","errorClass":"PropertyNotFoundException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstMethod.java","lineNumber":93,"sourceCode":"\t}\n\n\t@Override\n\tpublic void appendStructure(StringBuilder builder, Bindings bindings) {\n\t\tproperty.appendStructure(builder, bindings);\n\t\tparams.appendStructure(builder, bindings);\n\t}\n\n\tprotected Object eval(Bindings bindings, ELContext context, boolean answerNullIfBaseIsNull) {\n\t\tObject base = property.getPrefix().eval(bindings, context);\n\t\tif (base == null) {\n\t\t\tif (answerNullIfBaseIsNull) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.base.null\", property.getPrefix()));\n\t\t}\n\t\tObject method = property.getProperty(bindings, context);\n\t\tif (method == null) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.method.notfound\", \"null\", base));\n\t\t}\n\t\tString name = bindings.convert(method, String.class);\n\n\t\tcontext.setPropertyResolved(false);\n\t\tObject result = context.getELResolver().invoke(context, base, name, null, params.eval(bindings, context));\n\t\tif (!context.isPropertyResolved()) {\n\t\t\tthrow new MethodNotFoundException(LocalMessages.get(\"error.property.method.notfound\", name, base.getClass()));\n\t\t}\n\t\treturn result;\n\t}\n\n\t@Override\n\tpublic Object eval(Bindings bindings, ELContext context) {\n\t\treturn eval(bindings, context, true);\n\t}\n\n    @Override\n\tpublic Object invoke(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes, Object[] paramValues) {","sourceCodeStart":75,"sourceCodeEnd":111,"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/AstMethod.java#L75-L111","documentation":"After resolving the base object, AstMethod.eval asks the property node for the method name; if the property itself is null it throws PropertyNotFoundException('error.property.method.notfound' with name 'null'). This indicates the method-name part of the method expression evaluated to null rather than a String.","triggerScenarios":"Dynamic method access like ${obj[methodName]()} or bracket-style method selection where the inner expression returns null (unset variable, missing map key, resolver returning null).","commonSituations":"Dynamic dispatch from a configuration variable that was never set; map lookup for the method name returning null because the key is absent; expression built programmatically with a null method token.","solutions":["Ensure the variable/expression providing the method name is non-null and a non-empty String before evaluation.","Default the name: ${obj[name != null ? name : 'defaultMethod']()} — or fix the map key/config value.","Validate inputs feeding the dynamic method name (empty check) upstream.","Switch to an explicit static method call if dynamic dispatch is not truly needed."],"exampleFix":"// before\n${bean[fnName]()}  // fnName is null\n// after\n${bean[fnName != null ? fnName : 'defaultFn']()}","handlingStrategy":"validation","validationCode":"String methodName = (String) factory.createValueExpression(ctx, \"${fnName}\", String.class).getValue(context);\nif (methodName == null || methodName.isEmpty()) {\n    throw new IllegalStateException(\"Dynamic method name must be a non-empty String\");\n}","typeGuard":"boolean validDynamicMethodName(String s) { return s != null && !s.trim().isEmpty(); }","tryCatchPattern":"try {\n    return expr.getValue(context);\n} catch (PropertyNotFoundException e) {\n    if (!e.getMessage().contains(\"method.notfound\")) throw e;\n    return fallbackMethod();\n}","preventionTips":["Validate variables feeding dynamic method selection before evaluation","Provide defaults for dynamic method-name variables","Prefer static method calls when dispatch target is known at authoring time"],"tags":["el","expression-language","dynamic-method","null"],"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"}