apache/skywalking · error · IllegalArgumentException
Expected String argument for extension function, got {}
Error message
Expected String argument for extension function, got {} What it means
Thrown by MALMethodChainCodegen.generateExtensionArg when the extension method declares a String parameter but the corresponding MAL argument is not a string literal (not a MALExpressionModel.StringArgument). Only String literals can be spliced into generated Java source for String parameters, so number literals or list literals are rejected.
Source
Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALMethodChainCodegen.java:186
}
sb.append(");\n");
}
/**
* Generates a typed argument for an extension function call.
* Emits raw literals: {@code 3.0}, {@code 10L}, {@code 3.0F}, {@code 10}.
*/
private void generateExtensionArg(final StringBuilder sb,
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");
}View on GitHub (pinned to 102af09b4a)
Solutions
- Pass a double-quoted string literal for every String parameter
- If the value is semantically numeric, change the Java parameter to double/int/long instead
- Check for stray quotes/typos: 'myext::f(env)' parses as an expression, not a string — write myext::f("env")
Example fix
# before
expr: m.sum([]).myext::withPrefix(100)
# after
expr: m.sum([]).myext::withPrefix("100") Defensive patterns
Strategy: type-guard
Type guard
// pseudo: check each MAL argument kind against the Java param type before compile
boolean matches(MALExpressionModel.Argument a, Class<?> p) {
if (p == String.class) return a instanceof MALExpressionModel.StringArgument;
return true; // other checks for numbers/lists
} Try / catch
catch IllegalArgumentException at compile time; include the extension signature in the error report
Prevention
- Use double quotes for string arguments, single quotes only inside closures
- Lint rule files for quoted-number arguments to extension calls
When it happens
Trigger: Extension 'f(SampleFamily, String prefix)' invoked as '.myext::f(100)' or '.myext::f(["a","b"])' — the argument node is an ExprArgument/StringListArgument instead of StringArgument. String literals must use double quotes in MAL.
Common situations: Using single quotes (MAL filter-closure style) instead of double quotes for string arguments in an extension call; passing a numeric tag value where a string key is expected; forgetting quotes entirely so the parser treats the token as an identifier expression.
Related errors
- Expected number 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/9f7dcbc5877cbd0e.
Report an issue: GitHub.