apache/skywalking · error · IllegalArgumentException

Expected number argument for extension function

Error message

Expected number argument for extension function

What it means

Second-stage numeric check in MALMethodChainCodegen.generateExtensionArg: the argument IS an ExprArgument, but the inner expression is not a NumberExpr — the MAL grammar produced something like a boolean/null/identifier expression where the extension's numeric parameter needs a constant number literal that can be emitted as raw Java source.

Source

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

                  .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) {
                sb.append((long) raw).append('L');
            } else {
                sb.append((int) raw);
            }
        } else if (List.class.isAssignableFrom(expectedType)) {
            if (arg instanceof MALExpressionModel.StringListArgument) {
                final List<String> values =

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Replace the argument with a constant numeric literal
  2. If you need dynamic values, do the computation inside the extension method body (e.g. read it from the SampleFamily or configuration) rather than as a MAL argument
  3. Restructure the rule so the extension receives the metric via the implicit SampleFamily parameter

Example fix

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

# after
expr: m.sum([]).myext::scale(2.0)  # constants only; compute dynamics inside the extension
Defensive patterns

Strategy: type-guard

Type guard

boolean isConstantNumber(MALExpressionModel.Argument a) {
    return a instanceof MALExpressionModel.ExprArgument
        && ((MALExpressionModel.ExprArgument) a).getExpr()
            instanceof MALExpressionModel.NumberExpr;
}

Try / catch

catch IllegalArgumentException at compile time; tell the author extension params must be constant literals

Prevention

When it happens

Trigger: '.myext::scale(otherMetric)' (identifier reference), '.myext::scale(true)', or any non-numeric expression passed to a double/int/long/float parameter. Only constant number literals can be inlined into the generated static call.

Common situations: Trying to parameterize an extension with another metric or a computed expression — extension extra params must be compile-time constants; passing YAML-inherited booleans.

Related errors


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