{"record":{"id":"9a833bd12299509d","repo":"apache/skywalking","slug":"oal-parsing-failed-with-n-error-s-errors","errorCode":null,"errorMessage":"OAL parsing failed with {n} error(s): {errors}","messagePattern":"OAL parsing failed with (.+?) error\\(s\\): (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/v2/parser/OALScriptParserV2.java","lineNumber":119,"sourceCode":"        OALLexer lexer = new OALLexer(CharStreams.fromReader(reader));\n\n        // Create token stream\n        CommonTokenStream tokens = new CommonTokenStream(lexer);\n\n        // Create parser\n        OALParser parser = new OALParser(tokens);\n\n        // Add custom error listener to collect detailed error information\n        OALErrorListener errorListener = new OALErrorListener(fileName);\n        parser.removeErrorListeners(); // Remove default console error listener\n        parser.addErrorListener(errorListener);\n\n        // Parse the script\n        OALParser.RootContext root = parser.root();\n\n        // Check for syntax errors\n        if (errorListener.hasErrors()) {\n            throw new IllegalArgumentException(errorListener.getFormattedErrors());\n        }\n\n        // Walk the parse tree with V2 listener\n        OALListenerV2 listener = new OALListenerV2(fileName);\n        ParseTreeWalker walker = new ParseTreeWalker();\n        walker.walk(listener, root);\n\n        return new OALScriptParserV2(listener.getMetrics(), listener.getDisabledSources(), fileName);\n    }\n\n    /**\n     * Get metrics count.\n     */\n    public int getMetricsCount() {\n        return metrics.size();\n    }\n\n    /**","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/v2/parser/OALScriptParserV2.java#L101-L137","documentation":"OALScriptParserV2 drives ANTLR parsing of an .oal script with a custom OALErrorListener attached (default console listeners removed). After parser.root() completes, any syntax errors collected by the listener are thrown as one IllegalArgumentException carrying all formatted errors (file, line, column). This is the first gate every OAL script passes through, whether at OAP startup or when installing a dynamic OAL rule.","triggerScenarios":"A .oal file (core OAL metrics, custom oal/*.oal, or an OAL rule submitted via dynamic configuration / dsl-debugging) contains a grammar violation: missing '-->' or metric name, bad source expression, unbalanced parentheses, stray characters, or misuse of filter/cast syntax.","commonSituations":"Editing custom OAL files under oap-server/server-starter resources or the dynamic-configuration OAL rule; typos after copy-pasting metric definitions; using grammar features from a newer version on an older OAP; trailing semicolons or comments not supported by the grammar.","solutions":["Read the formatted errors in the message: each includes file name, line, and column of the offending token; fix the first error first (later ones are often cascades)","Compare your rule against working rules in oap-server/server-starter/src/main/resources/oal/*.oal for exact syntax (source expression, optional where-filter, '-->', metric name)","Validate the script in a scratch setup or via the dsl-debugging API before deploying to a live OAP","If the script was fine before an upgrade, check the changelog for grammar changes between versions"],"exampleFix":"// before (OAL, missing '-->' target name)\nsvc_sla = from Service.sla -->\n// after\nsvc_sla = from Service.sla --> serviceSla;","handlingStrategy":"try-catch","validationCode":"// Pre-validate a rule string before pushing it via dynamic configuration (pseudocode):\ntry {\n    OALScriptParserV2.parse(script, \"preview.oal\");\n} catch (IllegalArgumentException e) {\n    reject(\"OAL syntax invalid: \" + e.getMessage());\n}","typeGuard":null,"tryCatchPattern":"Catch IllegalArgumentException around the parse call in tooling (CLI, dsl-debugging install handler) and return the formatted errors (file/line/column) to the caller verbatim; let OAP boot fail fast on bad shipped .oal files so misconfiguration is visible.","preventionTips":["Compile-test all shipped and dynamic OAL rules in CI by parsing them with OALScriptParserV2","Fix the first reported syntax error first — later errors are frequently cascades","Copy rule structure from oap-server/server-starter/src/main/resources/oal/*.oal rather than writing from memory"],"tags":["oal","parsing","antlr","configuration"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}