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
- Remove quotes and pass a bare numeric literal: .myext::scale(2.0)
- Keep the Java parameter as String and parse inside the method if you genuinely need flexible input
- 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
- Never quote numeric extension arguments
- Keep String-vs-number parameter conventions documented per extension function
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
- Expected String argument for extension function, got {}
- MAL extension {}::{} expects {} argument(s), got {}
- Expected number argument for extension function
- Expected list argument for extension function, got {}
- Unknown MAL extension function: {}::{}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/8d5648a47a631df4.
Report an issue: GitHub.