{"record":{"id":"c4e7ffb66e8eb3f9","repo":"apache/skywalking","slug":"failed-to-compile-lal-expression-dsl","errorCode":null,"errorMessage":"Failed to compile LAL expression: {dsl}","messagePattern":"Failed to compile LAL expression: (.+?)","errorType":"exception","errorClass":"ModuleStartException","httpStatus":null,"severity":"critical","filePath":"oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/dsl/DSL.java","lineNumber":144,"sourceCode":"            // (otherwise debugHolder() returns null on the compiled expression).\n            final GateHolder holder = expression.debugHolder();\n            if (holder != null) {\n                final LinkedHashMap<String, String> meta = new LinkedHashMap<>();\n                if (ruleName != null && !ruleName.isEmpty()) {\n                    meta.put(\"ruleName\", ruleName);\n                }\n                if (outputType != null) {\n                    meta.put(\"outputClass\", outputType.getName());\n                }\n                if (inputType != null) {\n                    meta.put(\"inputClass\", inputType.getName());\n                }\n                holder.setMetadata(meta);\n            }\n            final FilterSpec filterSpec = new FilterSpec(moduleManager, config);\n            return new DSL(ruleName, expression, filterSpec, effectiveInputType);\n        } catch (Exception e) {\n            throw new ModuleStartException(\n                \"Failed to compile LAL expression: \" + dsl, e);\n        }\n    }\n\n    public void evaluate(final ExecutionContext ctx) {\n        if (log.isDebugEnabled()) {\n            final LogMetadata metadata = ctx.metadata();\n            log.debug(\"[LAL] rule={}, class={}, service={}, instance={}, endpoint={}\",\n                ruleName, expression.getClass().getName(),\n                metadata.getService(), metadata.getServiceInstance(),\n                metadata.getEndpoint());\n        }\n        expression.execute(filterSpec, ctx);\n    }\n}\n","sourceCodeStart":126,"sourceCodeEnd":160,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/log-analyzer/src/main/java/org/apache/skywalking/oap/log/analyzer/v2/dsl/DSL.java#L126-L160","documentation":"Top-level wrapper: DSL.of(...) compiles the LAL DSL (ANTLR parse → AST → Javassist class generation → class load) and wraps ANY exception thrown in that pipeline in a ModuleStartException whose message embeds the full DSL text. The root cause (parse error, codegen IllegalArgumentException, Javassist compile failure, Class.forName miss) is always in the cause chain. Because it is a ModuleStartException, an unhandled occurrence aborts OAP startup or a runtime-rule update.","triggerScenarios":"Any DSL.of call — startup loadStaticRules or the runtime-rule path — where the rule text fails parsing or codegen: unknown fields, bad tag() usage on typed input, missing getters on inputType, invalid casts, syntax errors; also Javassist CannotCompileException when generated Java is invalid (a compiler bug indicator).","commonSituations":"Deploying a hand-written LAL YAML with a syntax or semantic error; a runtime rule update pushed via the dynamic-config channel; upgrading SkyWalking where grammar keywords changed (e.g. slowSql/sampledTrace removal).","solutions":["Read the nested cause in the stack trace (getCause()) — the wrapper message only echoes the DSL, the cause names the actual problem and codegen line","Fix the underlying rule error per the cause message (unknown field, arity, cast, getter, etc.)","Validate the rule against the shipped lal/*.yaml examples and the grammar before deploying","If the cause is CannotCompileException with no obvious rule error, check for generated-Java issues and report with SW_DYNAMIC_CLASS_ENGINE_DEBUG=true dumps"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    DSL dsl = DSL.of(moduleManager, config, dslText, inputType, outputType, ruleName, sourceRef, null, null);\n} catch (ModuleStartException e) {\n    // The DSL text is in e.getMessage(); the REAL reason is in the cause chain.\n    Throwable root = e;\n    while (root.getCause() != null && root.getCause() != root) root = root.getCause();\n    log.error(\"LAL rule {} rejected: {} at {}\", ruleName, root.getMessage(), root.getStackTrace()[0]);\n    // keep the previously active rule bundle; surface the error to the operator\n}","preventionTips":["Always inspect the deepest cause, not the wrapper message","Compile candidate rules in a staging environment before enabling them at runtime","Use SW_DYNAMIC_CLASS_ENGINE_DEBUG=true to dump generated Java when causes are unclear"],"tags":["lal","log-analyzer","compiler","startup","wrapper"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}