{"record":{"id":"ae47443346479ade","repo":"apache/skywalking","slug":"mal-extension-expects-argument-s-got","errorCode":null,"errorMessage":"MAL extension {}::{} expects {} argument(s), got {}","messagePattern":"MAL extension (.+?)::(.+?) expects (.+?) argument\\(s\\), got (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALMethodChainCodegen.java","lineNumber":157,"sourceCode":"     *\n     * <p>For {@code .test::scale(3.0)} on variable {@code _metric}, generates:\n     * {@code _metric = TestMalExtension.scale(_metric, 3.0);}\n     */\n    private void emitExtensionCall(final StringBuilder sb,\n                                    final String var,\n                                    final MALExpressionModel.MethodCall mc) {\n        final String ns = mc.getNamespace();\n        final String method = mc.getName();\n        final MalExtensionRegistry.ExtensionMethod em =\n            MalExtensionRegistry.lookup(ns, method);\n        if (em == null) {\n            throw new IllegalArgumentException(\n                \"Unknown MAL extension function: \" + ns + \"::\" + method);\n        }\n        final List<MALExpressionModel.Argument> args = mc.getArguments();\n        final int expectedArgs = em.getExtraParamTypes().length;\n        if (args.size() != expectedArgs) {\n            throw new IllegalArgumentException(\n                \"MAL extension \" + ns + \"::\" + method + \" expects \"\n                    + expectedArgs + \" argument(s), got \" + args.size());\n        }\n        sb.append(\"  \").append(var).append(\" = \")\n          .append(em.getDeclaringClass()).append('.')\n          .append(em.getMethodName()).append('(')\n          .append(var);\n        for (int i = 0; i < args.size(); i++) {\n            sb.append(\", \");\n            generateExtensionArg(sb, args.get(i), em.getExtraParamTypes()[i]);\n        }\n        sb.append(\");\\n\");\n    }\n\n    /**\n     * Generates a typed argument for an extension function call.\n     * Emits raw literals: {@code 3.0}, {@code 10L}, {@code 3.0F}, {@code 10}.\n     */","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALMethodChainCodegen.java#L139-L175","documentation":"Thrown by MALMethodChainCodegen when a namespace::method() extension call passes a number of MAL arguments that does not match the Java method's parameter count minus the implicit SampleFamily first parameter (expectedArgs = em.getExtraParamTypes().length). The compiler needs an exact arity match to emit a direct static call, so mismatched counts abort compilation.","triggerScenarios":"Extension 'public static SampleFamily filterTag(SampleFamily sf, String key, String value)' invoked as '.myext::filterTag(\"env\")' (1 arg, expects 2), or a zero-extra-param method called with arguments '.myext::noop(1.0)'.","commonSituations":"Extending an extension method signature in a new jar version (added parameter) while rules still use the old call shape; copy-pasting an example rule that targets a different version of the extension.","solutions":["Count the arguments in the MAL call and make them equal to the Java method's parameters after the SampleFamily one","If the extension method changed, update the rule YAML to pass the new argument","Provide overloaded @MALContextFunction methods with distinct arities only if they have different Java names (same-name duplicates are rejected by the registry)"],"exampleFix":"// extension\n@MALContextFunction\npublic static SampleFamily filterTag(SampleFamily sf, String key, String value) { ... }\n\n# before\nexpr: m.sum([]).myext::filterTag(\"env\")\n\n# after\nexpr: m.sum([]).myext::filterTag(\"env\", \"prod\")","handlingStrategy":"validation","validationCode":"MalExtensionRegistry.ExtensionMethod em = MalExtensionRegistry.lookup(ns, method);\nif (em != null && callArgs.size() != em.getExtraParamTypes().length) {\n    throw new IllegalArgumentException(ns + \"::\" + method + \" expects \"\n        + em.getExtraParamTypes().length + \" args, got \" + callArgs.size());\n}","typeGuard":null,"tryCatchPattern":"catch IllegalArgumentException at rule compile; report expected vs actual arity to the rule author","preventionTips":["Keep a table of extension signatures next to the rule templates","When changing an extension method's parameters, grep all rule YAMLs for the ns::method call sites"],"tags":["mal","extension","arguments","configuration"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}