apache/skywalking · error · IllegalArgumentException
@MALContextFunction {}.{}() List parameters must be List<Str
Error message
@MALContextFunction {}.{}() List parameters must be List<String>, got {} What it means
SPI validation error from MalExtensionRegistry: a @MALContextFunction method declares a List parameter whose generic element type is not String (e.g. List<Double>, List<Object>, or a raw/generic-wildcard type whose actual type argument is not exactly String.class). List<String> is the only list type the MAL argument codegen supports (StringListArgument emits Arrays.asList(new String[]{...})), so anything else is rejected at registration.
Source
Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/rt/MalExtensionRegistry.java:106
}
if (!SampleFamily.class.isAssignableFrom(m.getReturnType())) {
throw new IllegalArgumentException(
"@MALContextFunction " + ext.getClass().getSimpleName()
+ "." + m.getName()
+ "() return type must be SampleFamily");
}
final Class<?>[] extraParamTypes = new Class<?>[paramTypes.length - 1];
System.arraycopy(paramTypes, 1, extraParamTypes, 0, extraParamTypes.length);
// Validate List params use List<String> (the only List type MAL supports)
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 {}::{}() -> {}.{}()",View on GitHub (pinned to 102af09b4a)
Solutions
- Declare the parameter as exactly List<String>
- If numbers are needed, take a String list and parse each element inside the method (Double.parseDouble), or take a double/int scalar
- Rebuild the extension jar and restart OAP
Example fix
// before
@MALContextFunction
public static SampleFamily f(SampleFamily sf, List<Double> buckets) { ... }
// after
@MALContextFunction
public static SampleFamily f(SampleFamily sf, List<String> buckets) {
List<Double> parsed = buckets.stream().map(Double::parseDouble).collect(java.util.stream.Collectors.toList());
...
} Defensive patterns
Strategy: validation
Validate before calling
Type[] gpts = m.getGenericParameterTypes();
for (int i = 1; i < gpts.length; i++) {
if (gpts[i] instanceof ParameterizedType
&& ((ParameterizedType) gpts[i]).getRawType() == List.class
&& ((ParameterizedType) gpts[i]).getActualTypeArguments()[0] != String.class) {
throw new IllegalArgumentException("List params must be List<String>: " + m);
}
} Try / catch
startup-time; fix the generic signature and redeploy
Prevention
- Only List<String> is supported; parse numerics inside the method
- Avoid raw List and wildcard generics on annotated methods
When it happens
Trigger: A method like 'f(SampleFamily, List<Double> buckets)' — the registry inspects m.getGenericParameterTypes(), finds a ParameterizedType for a List param, and the first actual type argument is not String. Note: a raw List (no generic type) slips past this check but then fails argument codegen differently — declare List<String> explicitly.
Common situations: Wanting numeric bucket lists for histogram-like extensions; using raw List from older Java code; wildcard List<? extends String> also fails the String.class.equals check.
Related errors
- @MALContextFunction {}.{}() must be static
- @MALContextFunction {}.{}() first parameter must be SampleFa
- @MALContextFunction {}.{}() return type must be SampleFamily
- Duplicate @MALContextFunction name '{}' in namespace '{}' fr
- Duplicate MAL extension namespace '{}' from {}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/aa68c520e975bd82.
Report an issue: GitHub.