apache/skywalking · error · IllegalArgumentException

Expected list argument for extension function, got {}

Error message

Expected list argument for extension function, got {}

What it means

Thrown by MALMethodChainCodegen.generateExtensionArg when the extension method declares a List parameter (only List<String> is supported) but the MAL argument node is not a StringListArgument — e.g. a bare string, a number, or a single identifier was passed where a ['a','b'] list literal is required.

Source

Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALMethodChainCodegen.java:233

            } else {
                sb.append((int) raw);
            }
        } else if (List.class.isAssignableFrom(expectedType)) {
            if (arg instanceof MALExpressionModel.StringListArgument) {
                final List<String> values =
                    ((MALExpressionModel.StringListArgument) arg).getValues();
                sb.append("java.util.Arrays.asList(new String[]{");
                for (int i = 0; i < values.size(); i++) {
                    if (i > 0) {
                        sb.append(", ");
                    }
                    sb.append('"')
                      .append(DslJavaSourceText.toLiteral(values.get(i)))
                      .append('"');
                }
                sb.append("})");
            } else {
                throw new IllegalArgumentException(
                    "Expected list argument for extension function, got "
                        + arg.getClass().getSimpleName());
            }
        } else {
            throw new IllegalArgumentException(
                "Unsupported extension parameter type: "
                    + expectedType.getName());
        }
    }

    // ==================== Argument codegen ====================

    /**
     * Generates a method call argument with special handling for primitive double methods.
     * For {@code .valueEqual(33)}: emits raw {@code 33.0}.
     * For {@code .multiply(100)}: emits boxed {@code Long.valueOf(100L)}.
     */
    private void generateMethodCallArg(final StringBuilder sb,

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Wrap the values in a bracketed string list literal: .myext::fn(['svc', 'instance'])
  2. Single-element lists still need brackets: .myext::fn(['svc'])
  3. If a single value is intended, keep the Java parameter as String instead of List<String>

Example fix

# before
expr: m.sum([]).myext::rollup("svc")

# after
expr: m.sum([]).myext::rollup(['svc'])
Defensive patterns

Strategy: type-guard

Type guard

boolean isStringList(MALExpressionModel.Argument a) {
    return a instanceof MALExpressionModel.StringListArgument;
}

Try / catch

catch IllegalArgumentException at compile time; show the expected ['a','b'] list syntax

Prevention

When it happens

Trigger: Extension 'sum(SampleFamily, List<String> labels)' invoked as '.myext::sum("svc")' or '.myext::sum(100)' instead of '.myext::sum([\'svc\'])'.

Common situations: Confusing the extension list syntax with the built-in sum()/avg() style — built-ins also need bracket lists, but authors sometimes drop them for single-element lists; switching a String param to List<String> and leaving old rules unchanged.

Related errors


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