{"record":{"id":"28e5a2833502db0f","repo":"elastic/elasticsearch","slug":"no-execute-method-found","errorCode":null,"errorMessage":"no execute method found","messagePattern":"no execute method found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java","lineNumber":99,"sourceCode":"                                + \"type [\"\n                                + componentType.getName()\n                                + \"]. Painless can only support getters with return types that are \"\n                                + \"whitelisted.\"\n                        )\n                    );\n\n                    getMethods.add(\n                        new org.objectweb.asm.commons.Method(\n                            m.getName(),\n                            MethodType.methodType(m.getReturnType()).toMethodDescriptorString()\n                        )\n                    );\n\n                }\n        }\n\n        if (executeMethod == null) {\n            throw new IllegalStateException(\"no execute method found\");\n        }\n        ArrayList<FunctionTable.LocalFunction> converters = new ArrayList<>();\n        FunctionTable.LocalFunction defConverter = null;\n        for (java.lang.reflect.Method m : baseClass.getMethods()) {\n            if (m.getName().startsWith(\"convertFrom\")\n                && m.getParameterTypes().length == 1\n                && m.getReturnType() == returnType\n                && Modifier.isStatic(m.getModifiers())) {\n\n                if (m.getName().equals(\"convertFromDef\")) {\n                    if (m.getParameterTypes()[0] != Object.class) {\n                        throw new IllegalStateException(\n                            \"convertFromDef must take a single Object as an argument, \" + \"not [\" + m.getParameterTypes()[0] + \"]\"\n                        );\n                    }\n                    defConverter = new FunctionTable.LocalFunction(\n                        m.getName(),\n                        m.getReturnType(),","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java#L81-L117","documentation":"After iterating all non-default methods of the context interface, ScriptClassInfo asserts that an execute method was found. If none is present, this IllegalStateException is thrown. Every Painless-implementable interface must declare a single non-default method literally named execute.","triggerScenarios":"Registering a custom ScriptContext whose interface has no method named execute (e.g. it was named run, apply, or compute), or whose only execute is a default method (default methods are skipped by the loop at line 55-56).","commonSituations":"Renaming execute to a different method name during a refactor; implementing a functional interface from another framework verbatim; making execute a default method by accident.","solutions":["Add a non-default method named 'execute' to the interface returning a whitelisted type.","If the method exists but is marked default, remove the default keyword so it becomes abstract.","Confirm the interface is the one actually passed as baseClass to ScriptClassInfo."],"exampleFix":"// before\npublic interface MyScript {\n    default double execute() { return 0; } // skipped -> 1342\n}\n// after\npublic interface MyScript {\n    double execute();\n}","handlingStrategy":"validation","validationCode":"void assertHasExecute(Class<?> iface) {\n    boolean has = java.util.Arrays.stream(iface.getMethods())\n        .anyMatch(m -> !m.isDefault() && m.getName().equals(\"execute\"));\n    if (!has) throw new IllegalStateException(\"interface needs a non-default execute method\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    new ScriptClassInfo(lookup, MyScript.class);\n} catch (IllegalStateException e) {\n    if (e.getMessage().equals(\"no execute method found\")) {\n        fail(\"Add a non-default 'execute' method to \" + MyScript.class.getName());\n    }\n    throw e;\n}","preventionTips":["Always name the entry method 'execute' (not run/apply).","Do not mark execute as default.","Add a compile-time-style reflection test in your context's unit tests."],"tags":["painless","scripting","script-context","reflection","elasticsearch"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}