{"record":{"id":"46ad81a80910cc03","repo":"apache/skywalking","slug":"duplicate-malcontextfunction-name-in-namespa","errorCode":null,"errorMessage":"Duplicate @MALContextFunction name '{}' in namespace '{}' from {}","messagePattern":"Duplicate @MALContextFunction name '(.+?)' in namespace '(.+?)' from (.+?)","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/rt/MalExtensionRegistry.java","lineNumber":116,"sourceCode":"            final Type[] genericTypes = m.getGenericParameterTypes();\n            for (int i = 1; i < genericTypes.length; i++) {\n                if (List.class.isAssignableFrom(extraParamTypes[i - 1])\n                        && genericTypes[i] instanceof ParameterizedType) {\n                    final Type elementType =\n                        ((ParameterizedType) genericTypes[i])\n                            .getActualTypeArguments()[0];\n                    if (!String.class.equals(elementType)) {\n                        throw new IllegalArgumentException(\n                            \"@MALContextFunction \" + ext.getClass().getSimpleName()\n                                + \".\" + m.getName()\n                                + \"() List parameters must be List<String>, got \"\n                                + genericTypes[i]);\n                    }\n                }\n            }\n            final String methodName = m.getName();\n            if (methods.containsKey(methodName)) {\n                throw new IllegalArgumentException(\n                    \"Duplicate @MALContextFunction name '\" + methodName\n                        + \"' in namespace '\" + namespace\n                        + \"' from \" + ext.getClass().getName());\n            }\n            final String fqcn = m.getDeclaringClass().getName();\n            methods.put(methodName,\n                        new ExtensionMethod(fqcn, methodName, extraParamTypes));\n            log.info(\"Registered MAL extension function {}::{}() -> {}.{}()\",\n                     namespace, methodName, fqcn, methodName);\n        }\n        if (!methods.isEmpty()) {\n            if (REGISTRY.containsKey(namespace)) {\n                throw new IllegalArgumentException(\n                    \"Duplicate MAL extension namespace '\" + namespace\n                        + \"' from \" + ext.getClass().getName());\n            }\n            REGISTRY.put(namespace, methods);\n        }","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/rt/MalExtensionRegistry.java#L98-L134","documentation":"SPI validation error from MalExtensionRegistry: two methods annotated @MALContextFunction within the same MalFunctionExtension implementation share the same Java method name. Since MAL resolves calls as namespace::methodName and generated code is a plain static call by name, a namespace cannot export overloads — the second registration aborts with IllegalArgumentException.","triggerScenarios":"Defining 'f(SampleFamily)' and 'f(SampleFamily, String)' in the same extension class, both annotated. methods.containsKey(methodName) is true when the second one registers.","commonSituations":"Natural Java overloading instinct when adding a convenience variant of an existing extension function; merging two extension classes that both define a method with the same name into one namespace.","solutions":["Give each variant a distinct method name, e.g. filter() and filterWithValue(String)","Keep a single method with the full parameter list and let rules pass all arguments","Split the functions into two namespaces (two MalFunctionExtension implementations with different name()) if the overloads are conceptually separate"],"exampleFix":"// before\n@MALContextFunction public static SampleFamily f(SampleFamily sf) { ... }\n@MALContextFunction public static SampleFamily f(SampleFamily sf, String k) { ... }\n\n// after\n@MALContextFunction public static SampleFamily f(SampleFamily sf) { ... }\n@MALContextFunction public static SampleFamily fByKey(SampleFamily sf, String k) { ... }","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (Method m : ext.getClass().getMethods()) {\n    if (m.isAnnotationPresent(MALContextFunction.class) && !seen.add(m.getName())) {\n        throw new IllegalArgumentException(\"Overloaded @MALContextFunction \" + m.getName());\n    }\n}","typeGuard":null,"tryCatchPattern":"startup-time; rename the overloads and redeploy","preventionTips":["One name, one signature per namespace — no Java overloading","Namespaces isolate names; split unrelated functions into separate namespaces"],"tags":["mal","extension","spi","duplicate","startup"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}