apache/skywalking · error · IllegalArgumentException

Expected number argument for extension function, got {}

Error message

Expected number argument for extension function, got {}

What it means

Thrown by MALMethodChainCodegen.generateExtensionArg when the extension method declares a numeric parameter (double/Double, float/Float, long/Long, int/Integer) but the MAL argument is not an expression argument (MALExpressionModel.ExprArgument) — e.g. a string literal or string list was passed where a number is required.

Source

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

                                       final MALExpressionModel.Argument arg,
                                       final Class<?> expectedType) {
        if (expectedType == String.class) {
            if (arg instanceof MALExpressionModel.StringArgument) {
                sb.append('"')
                  .append(DslJavaSourceText.toLiteral(
                      ((MALExpressionModel.StringArgument) arg).getValue()))
                  .append('"');
            } else {
                throw new IllegalArgumentException(
                    "Expected String argument for extension function, got "
                        + arg.getClass().getSimpleName());
            }
        } else if (expectedType == double.class || expectedType == Double.class
                || expectedType == float.class || expectedType == Float.class
                || expectedType == long.class || expectedType == Long.class
                || expectedType == int.class || expectedType == Integer.class) {
            if (!(arg instanceof MALExpressionModel.ExprArgument)) {
                throw new IllegalArgumentException(
                    "Expected number argument for extension function, got "
                        + arg.getClass().getSimpleName());
            }
            final MALExpressionModel.Expr expr =
                ((MALExpressionModel.ExprArgument) arg).getExpr();
            if (!(expr instanceof MALExpressionModel.NumberExpr)) {
                throw new IllegalArgumentException(
                    "Expected number argument for extension function");
            }
            final double raw =
                ((MALExpressionModel.NumberExpr) expr).getValue();
            if (expectedType == double.class || expectedType == Double.class) {
                sb.append(raw);
            } else if (expectedType == float.class
                    || expectedType == Float.class) {
                sb.append((float) raw).append('F');
            } else if (expectedType == long.class
                    || expectedType == Long.class) {

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Remove quotes and pass a bare numeric literal: .myext::scale(2.0)
  2. Keep the Java parameter as String and parse inside the method if you genuinely need flexible input
  3. Update all rules referencing the extension after changing its signature

Example fix

# before
expr: m.sum([]).myext::scale("2.0")

# after
expr: m.sum([]).myext::scale(2.0)
Defensive patterns

Strategy: type-guard

Type guard

boolean isNumericArg(MALExpressionModel.Argument a) {
    return a instanceof MALExpressionModel.ExprArgument;
}

Try / catch

catch IllegalArgumentException at compile time; log the offending argument text from the rule

Prevention

When it happens

Trigger: Extension 'scale(SampleFamily, double factor)' invoked as '.myext::scale("2.0")' or '.myext::scale(["2"])'. The first check tests the argument node type before the inner expression is examined.

Common situations: Quoting numeric arguments out of habit from label-name arguments of built-ins like sum(['svc']); switching an extension parameter from String to double without updating the rules.

Related errors


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