apache/skywalking · error · IllegalArgumentException
MAL filter expression parsing failed: {} in expression: {}
Error message
MAL filter expression parsing failed: {} in expression: {} What it means
Parse failure specific to filter closure expressions: MALScriptParser parses a standalone filterExpression (the filter: block text like "{ tags -> tags.job_name == 'mysql-monitoring' }") into a ClosureArgument, and any ANTLR syntax error inside the closure aborts with IllegalArgumentException. Filter closures have their own grammar entry point, stricter than general expressions.
Source
Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALScriptParser.java:269
final MALParser parser = new MALParser(tokens);
final List<String> errors = new ArrayList<>();
parser.removeErrorListeners();
parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(final Recognizer<?, ?> recognizer,
final Object offendingSymbol,
final int line,
final int charPositionInLine,
final String msg,
final RecognitionException e) {
errors.add(line + ":" + charPositionInLine + " " + msg);
}
});
final MALParser.FilterExpressionContext tree = parser.filterExpression();
if (!errors.isEmpty()) {
throw new IllegalArgumentException(
"MAL filter expression parsing failed: " + String.join("; ", errors)
+ " in expression: " + filterExpression);
}
return new ClosureVisitor().visitClosure(tree.closureExpression());
}
/**
* Visitor transforming ANTLR4 parse tree into MAL expression AST.
*/
private static final class MALExprVisitor extends MALParserBaseVisitor<Expr> {
@Override
public Expr visitAdditiveExpression(final MALParser.AdditiveExpressionContext ctx) {
Expr result = visit(ctx.multiplicativeExpression(0));
for (int i = 1; i < ctx.multiplicativeExpression().size(); i++) {
final ArithmeticOp op = ctx.getChild(2 * i - 1).getText().equals("+")
? ArithmeticOp.ADD : ArithmeticOp.SUB;View on GitHub (pinned to 102af09b4a)
Solutions
- Check the closure has the exact shape { tags -> <boolean expr> } with single-quoted string literals
- Verify boolean operators are supported ones (==, !=, and, or / && , ||) per the MAL filter grammar
- Look at line:column in the message relative to the start of the filter string
- Test with MALScriptParser/MALClassGenerator.compileFilter in a unit test to iterate fast
Example fix
# before
filter: { tags -> tags.job_name == "mysql-monitoring" }
# after
filter: { tags -> tags.job_name == 'mysql-monitoring' } Defensive patterns
Strategy: try-catch
Validate before calling
try {
MALClassGenerator.compileFilter(filterText, ...);
} catch (Exception e) {
throw new AssertionError("Bad filter: " + e.getMessage());
} Try / catch
catch IllegalArgumentException around filter compilation; include the filter text and file in the error
Prevention
- Memorize the closure shape: { tags -> ... } with single-quoted strings
- Keep one canonical filter example in the repo docs and copy from it
When it happens
Trigger: A filter: block whose closure is malformed: missing '{' '}' braces, missing 'tags ->' parameter arrow, using double quotes where the closure grammar expects single-quoted strings, or an unsupported operator inside the closure body.
Common situations: Editing the file-level filter: in otel-rules YAMLs (e.g. filtering by job_name); quoting mistakes carried over from the rule expression style — inside closures string comparisons use single quotes ('value'), opposite of extension argument double quotes; copy-paste from docs that reformat the arrow.
Related errors
- MAL expression parsing failed while injecting expPrefix: {}
- MAL expression parsing failed: {} in expression: {}
- Load meter analyzer configs failed
- {slot} value '{numText}' exceeds the supported range (must f
- Unclosed interpolation in: {s}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/785c2a3006d8f206.
Report an issue: GitHub.