apache/skywalking · error · IllegalArgumentException

@MALContextFunction {}.{}() first parameter must be SampleFa

Error message

@MALContextFunction {}.{}() first parameter must be SampleFamily

What it means

SPI validation error from MalExtensionRegistry: a @MALContextFunction method's first parameter is missing or is not assignable to SampleFamily. The first parameter is the implicit receiver — the codegen passes the current chain value (a SampleFamily) as the first argument of the generated static call, so the signature must start with SampleFamily (or a supertype of it).

Source

Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/rt/MalExtensionRegistry.java:84

        if (namespace == null || namespace.isEmpty()) {
            log.warn("Skipping MalFunctionExtension with null/empty name: {}",
                     ext.getClass().getName());
            return;
        }
        final Map<String, ExtensionMethod> methods = new HashMap<>();
        for (final Method m : ext.getClass().getMethods()) {
            if (!m.isAnnotationPresent(MALContextFunction.class)) {
                continue;
            }
            if (!Modifier.isStatic(m.getModifiers())) {
                throw new IllegalArgumentException(
                    "@MALContextFunction " + ext.getClass().getSimpleName()
                        + "." + m.getName() + "() must be static");
            }
            final Class<?>[] paramTypes = m.getParameterTypes();
            if (paramTypes.length == 0
                    || !SampleFamily.class.isAssignableFrom(paramTypes[0])) {
                throw new IllegalArgumentException(
                    "@MALContextFunction " + ext.getClass().getSimpleName()
                        + "." + m.getName()
                        + "() first parameter must be SampleFamily");
            }
            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 =

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Make SampleFamily the first parameter: public static SampleFamily f(SampleFamily sf, <extra params...>)
  2. Any extra configuration parameters come after the SampleFamily one
  3. Rebuild and redeploy the extension jar, then restart OAP

Example fix

// before
@MALContextFunction
public static SampleFamily f(double factor) { ... }

// after
@MALContextFunction
public static SampleFamily f(SampleFamily sf, double factor) { ... }
Defensive patterns

Strategy: validation

Validate before calling

Class<?>[] pts = m.getParameterTypes();
if (pts.length == 0 || !SampleFamily.class.isAssignableFrom(pts[0])) {
    throw new IllegalArgumentException("First param must be SampleFamily: " + m);
}

Try / catch

startup-time; fail the extension's own unit test instead of catching at runtime

Prevention

When it happens

Trigger: Methods like 'f()' (zero params) or 'f(String key, SampleFamily sf)' / 'f(double factor)' where SampleFamily is not paramTypes[0]. The check requires paramTypes.length > 0 and SampleFamily.class.isAssignableFrom(paramTypes[0]).

Common situations: Porting a plain utility method and adding the annotation without reordering parameters; assuming the metric is passed some other way (return value, ThreadLocal); copy-paste from a non-MAL helper class.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/ef52752e27f08fe3. Report an issue: GitHub.