{"record":{"id":"785c2a3006d8f206","repo":"apache/skywalking","slug":"mal-filter-expression-parsing-failed-in-expres","errorCode":null,"errorMessage":"MAL filter expression parsing failed: {} in expression: {}","messagePattern":"MAL filter expression parsing failed: (.+?) in expression: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALScriptParser.java","lineNumber":269,"sourceCode":"        final MALParser parser = new MALParser(tokens);\n\n        final List<String> errors = new ArrayList<>();\n        parser.removeErrorListeners();\n        parser.addErrorListener(new BaseErrorListener() {\n            @Override\n            public void syntaxError(final Recognizer<?, ?> recognizer,\n                                    final Object offendingSymbol,\n                                    final int line,\n                                    final int charPositionInLine,\n                                    final String msg,\n                                    final RecognitionException e) {\n                errors.add(line + \":\" + charPositionInLine + \" \" + msg);\n            }\n        });\n\n        final MALParser.FilterExpressionContext tree = parser.filterExpression();\n        if (!errors.isEmpty()) {\n            throw new IllegalArgumentException(\n                \"MAL filter expression parsing failed: \" + String.join(\"; \", errors)\n                    + \" in expression: \" + filterExpression);\n        }\n\n        return new ClosureVisitor().visitClosure(tree.closureExpression());\n    }\n\n    /**\n     * Visitor transforming ANTLR4 parse tree into MAL expression AST.\n     */\n    private static final class MALExprVisitor extends MALParserBaseVisitor<Expr> {\n\n        @Override\n        public Expr visitAdditiveExpression(final MALParser.AdditiveExpressionContext ctx) {\n            Expr result = visit(ctx.multiplicativeExpression(0));\n            for (int i = 1; i < ctx.multiplicativeExpression().size(); i++) {\n                final ArithmeticOp op = ctx.getChild(2 * i - 1).getText().equals(\"+\")\n                    ? ArithmeticOp.ADD : ArithmeticOp.SUB;","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/MALScriptParser.java#L251-L287","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nfilter: { tags -> tags.job_name == \"mysql-monitoring\" }\n\n# after\nfilter: { tags -> tags.job_name == 'mysql-monitoring' }","handlingStrategy":"try-catch","validationCode":"try {\n    MALClassGenerator.compileFilter(filterText, ...);\n} catch (Exception e) {\n    throw new AssertionError(\"Bad filter: \" + e.getMessage());\n}","typeGuard":null,"tryCatchPattern":"catch IllegalArgumentException around filter compilation; include the filter text and file in the error","preventionTips":["Memorize the closure shape: { tags -> ... } with single-quoted strings","Keep one canonical filter example in the repo docs and copy from it"],"tags":["mal","filter","closure","parser","configuration"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}