{"record":{"id":"ab496a105f9a775e","repo":"apache/skywalking","slug":"failed-to-compile-mal-expression-for-metric-e","errorCode":null,"errorMessage":"Failed to compile MAL expression for metric: {}, expression: {}","messagePattern":"Failed to compile MAL expression for metric: (.+?), expression: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/dsl/DSL.java","lineNumber":119,"sourceCode":"            if (pool != null && targetClassLoader != null) {\n                // Per-file generator: one instance per compile is fine — it's just a thin\n                // orchestrator over ClassPool. Prevents cross-contamination of classNameHint /\n                // sourceRef state that the shared GENERATOR carries between calls.\n                final MALClassGenerator perFile = new MALClassGenerator(pool, targetClassLoader);\n                perFile.setSourceRef(sourceRef);\n                // The verbatim MAL expression text is the rule's \"content\" — threaded\n                // into the GateHolder so dsl-debugging records carry the rule source\n                // inline. Same string ANTLR parsed; no extra plumbing.\n                perFile.setContent(expression);\n                malExpr = perFile.compile(metricName, expression);\n            } else {\n                GENERATOR.setSourceRef(sourceRef);\n                GENERATOR.setContent(expression);\n                malExpr = GENERATOR.compile(metricName, expression);\n            }\n            return new Expression(metricName, expression, malExpr);\n        } catch (Exception e) {\n            throw new IllegalStateException(\n                \"Failed to compile MAL expression for metric: \" + metricName\n                    + \", expression: \" + expression, e);\n        }\n    }\n}\n","sourceCodeStart":101,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/dsl/DSL.java#L101-L125","documentation":"Wrapper exception from DSL.parse(metricName, expression, ...): it compiles the expression through the MALClassGenerator (Javassist bytecode generation), and any Exception in the pipeline — ANTLR parsing, metadata validation, extension lookup, argument type checks, or Javassist compile — is rethrown as IllegalStateException naming the metric and the full expression. This is the primary user-facing failure when a MAL rule cannot be compiled at OAP startup.","triggerScenarios":"DSL.parse invoked per rule during analyzer init; throws when the combined expression (expPrefix+exp+expSuffix) trips any earlier error in this catalog (49-51 parse, 42-48 extension, 40-41 decorate, 52-57 already thrown at registry init) or when Javassist rejects the generated source.","commonSituations":"Any malformed custom MAL rule file dropped into meter-analyzer-config / otel-rules / telegraf / zabbix / envoy rule directories; upgrading OAP to the v2 engine where previously-tolerated v1 expressions now fail; classpath issues with extension jars.","solutions":["Inspect e.getCause() — the real error and its message (one of the specific compiler errors) determines the fix","Fix the underlying issue in the rule YAML (syntax, quoting, scope, extension name/arity) and restart OAP","For Javassist-level failures, set SW_DYNAMIC_CLASS_ENGINE_DEBUG=true to dump the generated .java/.class and compare with what the compiler produced","Validate rules in a unit test using DSL.parse before deploying, so errors surface in CI rather than at OAP boot"],"exampleFix":"// before\nExpression e = DSL.parse(metricName, expression, sourceRef, pool, loader);\n\n// after\nExpression e;\ntry {\n    e = DSL.parse(metricName, expression, sourceRef, pool, loader);\n} catch (IllegalStateException ex) {\n    log.error(\"MAL rule '{}' failed to compile: {}\", metricName, ex.getCause().getMessage(), ex);\n    throw ex;\n}","handlingStrategy":"try-catch","validationCode":"try {\n    DSL.parse(metricName, expression, sourceRef, pool, targetClassLoader);\n} catch (IllegalStateException e) {\n    throw new AssertionError(\"Rule '\" + metricName + \"' invalid: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"catch IllegalStateException around each DSL.parse during rule loading; log metricName + expression + e.getCause(), and abort startup so a half-registered rule set cannot run","preventionTips":["Compile all custom MAL rules in CI with DSL.parse before deploying OAP","Set SW_DYNAMIC_CLASS_ENGINE_DEBUG=true when diagnosing codegen-stage failures to inspect generated .java","After OAP upgrades, run the shipped rule comparison tests to catch grammar/behavior drift"],"tags":["mal","wrapper","compile","configuration","startup"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}