apache/skywalking · error · ApplyException
LAL compile failed for rule '{name}' in {sourceName}
Error message
LAL compile failed for rule '{name}' in {sourceName} What it means
LalFileApplier.apply throws this ApplyException when factory.compile(...) fails for one LAL rule after some rules in the same file may have compiled. Because no registrations have landed at the compile phase, the partial list is empty and layer claims made in phase 1 are rolled back (layerRegistry.rollback(appliedClaims)) so no half-applied layer state leaks. The original compile Throwable (OAL-style grammar error in an expression, missing filter class, etc.) is attached as the cause.
Source
Thrown at oap-server/server-admin/runtime-rule/src/main/java/org/apache/skywalking/oap/server/receiver/runtimerule/apply/LalFileApplier.java:189
//
// Phase 2 — atomically swap into the factory registry. factory.addOrReplace is a
// volatile map write; a partial-failure window here is theoretical (Map.put
// doesn't throw). We still track progress per-rule so if somehow the JVM throws
// during phase 2, the caller's rollback list is accurate.
final List<LogFilterListener.Factory.CompiledLAL> compiled = new ArrayList<>(rules.size());
for (final LALConfig c : rules) {
// Shared with the boot loader, not restated: runtime rule names carry no extension,
// and the sourceName it derives keys the dsl-debugging registry, so a hot update must
// land on the same key as its disk-loaded twin rather than beside it.
LALConfigs.stampSource(c, sourceName);
try {
compiled.add(factory.compile(c, pool, ruleLoader));
} catch (final Throwable t) {
// Compile-phase failure: zero registrations landed, so partial is empty.
// Roll back the layer registrations done above so a failed compile does not
// leak runtime-layer state.
layerRegistry.rollback(appliedClaims);
throw new ApplyException(
"LAL compile failed for rule '" + c.getName() + "' in " + sourceName,
t, Collections.emptyList());
}
}
final List<RegisteredRule> registered = new ArrayList<>();
for (final LogFilterListener.Factory.CompiledLAL x : compiled) {
try {
// Cross-file collision guard: if another LAL file already owns (layer,
// ruleName), and we're not the prior holder (which would be a self-replace),
// reject — the registry's uniqueness invariant is per-layer within the
// cluster. Self-replace is safe because Phase 1 already succeeded and
// addOrReplace is the intended atomic takeover.
factory.addOrReplace(x);
registered.add(new RegisteredRule(x.layer, x.ruleName));
} catch (final Throwable t) {
// Roll back registrations made so far AND the layer claims. Rule-registration
// partial state survives in the caller's `partial` list for unwinding.View on GitHub (pinned to 102af09b4a)
Solutions
- Read the cause: it is the underlying LAL compile error naming the rule expression and position — fix that expression
- Test-compile the rule before hot-apply (dry-run/validate endpoint or a local OAP with the same version)
- Keep one rule per file during active development so a single bad expression doesn't roll back the whole file's layer claims
- After a failed apply, the applier already rolled back; verify no layer registrations remain via the runtime-layer admin view before retrying
Example fix
# before
- name: slow-api
exp: value > 1000 && tag.contains("url", "/api" # missing paren
# after
- name: slow-api
exp: value > 1000 && tag.contains("url", "/api") Defensive patterns
Strategy: try-catch
Try / catch
catch (LalFileApplier.ApplyException e) { // partial list is empty at compile phase — nothing to unwind
report rule name + e.getCause() (the LAL compile error); keep prior rule installed; no rollback action needed; } Prevention
- Test-compile each rule expression before bundling into a runtime file
- Keep one rule per file while iterating so compile failures roll back minimal layer claims
- Track grammar drift: recompile rule suites against the target OAP version in CI
When it happens
Trigger: Applying/hot-updating an LAL file where at least one rule's filter expression fails LAL compilation: invalid expression syntax, reference to a nonexistent provider/DSL function, or a regex that does not compile. The applier first claims layers, then compiles each stamped rule; the first failing rule aborts the whole file.
Common situations: Editing a LAL filter expression and introducing a grammar error (unbalanced quotes/parens); Referencing a time-based or JSON-path function not available in this OAP version; Rule compiles locally against a different OAP version than the running server (DSL grammar drift)
Related errors
- MAL compile failed for {sourceName}
- compile_failed
- LAL register failed for rule '{ruleName}' in {sourceName}
- LAL YAML parsed to empty/malformed — no rules list in {sourc
- LAL YAML parse failure for {sourceName}
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/bed1b2b45cdd71f6.
Report an issue: GitHub.