apache/skywalking · error · IllegalArgumentException
Duplicate @MALContextFunction name '{}' in namespace '{}' fr
Error message
Duplicate @MALContextFunction name '{}' in namespace '{}' from {} What it means
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.
Source
Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/rt/MalExtensionRegistry.java:116
final Type[] genericTypes = m.getGenericParameterTypes();
for (int i = 1; i < genericTypes.length; i++) {
if (List.class.isAssignableFrom(extraParamTypes[i - 1])
&& genericTypes[i] instanceof ParameterizedType) {
final Type elementType =
((ParameterizedType) genericTypes[i])
.getActualTypeArguments()[0];
if (!String.class.equals(elementType)) {
throw new IllegalArgumentException(
"@MALContextFunction " + ext.getClass().getSimpleName()
+ "." + m.getName()
+ "() List parameters must be List<String>, got "
+ genericTypes[i]);
}
}
}
final String methodName = m.getName();
if (methods.containsKey(methodName)) {
throw new IllegalArgumentException(
"Duplicate @MALContextFunction name '" + methodName
+ "' in namespace '" + namespace
+ "' from " + ext.getClass().getName());
}
final String fqcn = m.getDeclaringClass().getName();
methods.put(methodName,
new ExtensionMethod(fqcn, methodName, extraParamTypes));
log.info("Registered MAL extension function {}::{}() -> {}.{}()",
namespace, methodName, fqcn, methodName);
}
if (!methods.isEmpty()) {
if (REGISTRY.containsKey(namespace)) {
throw new IllegalArgumentException(
"Duplicate MAL extension namespace '" + namespace
+ "' from " + ext.getClass().getName());
}
REGISTRY.put(namespace, methods);
}View on GitHub (pinned to 102af09b4a)
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
Example fix
// before
@MALContextFunction public static SampleFamily f(SampleFamily sf) { ... }
@MALContextFunction public static SampleFamily f(SampleFamily sf, String k) { ... }
// after
@MALContextFunction public static SampleFamily f(SampleFamily sf) { ... }
@MALContextFunction public static SampleFamily fByKey(SampleFamily sf, String k) { ... } Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (Method m : ext.getClass().getMethods()) {
if (m.isAnnotationPresent(MALContextFunction.class) && !seen.add(m.getName())) {
throw new IllegalArgumentException("Overloaded @MALContextFunction " + m.getName());
}
} Try / catch
startup-time; rename the overloads and redeploy
Prevention
- One name, one signature per namespace — no Java overloading
- Namespaces isolate names; split unrelated functions into separate namespaces
When it happens
Trigger: Defining 'f(SampleFamily)' and 'f(SampleFamily, String)' in the same extension class, both annotated. methods.containsKey(methodName) is true when the second one registers.
Common situations: 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.
Related errors
- Duplicate MAL extension namespace '{}' from {}
- @MALContextFunction {}.{}() must be static
- @MALContextFunction {}.{}() first parameter must be SampleFa
- @MALContextFunction {}.{}() return type must be SampleFamily
- @MALContextFunction {}.{}() List parameters must be List<Str
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/46ad81a80910cc03.
Report an issue: GitHub.