apache/skywalking · warning · IllegalArgumentException
compile_failed
compile_failed
Error message
MAL YAML parse failure: {t.getMessage()} What it means
MalShapeExtractor.extract parses MAL YAML to derive each metric's shape (for delta classification); if snakeyaml loadAs throws, it wraps the cause in IllegalArgumentException with code compile_failed. Per the javadoc, callers are expected to treat shape extraction failures conservatively — the classifier falls back to the STRUCTURAL-with-over-approximation path — so a well-behaved caller catches this rather than propagating it. If you see it raw, the calling path did not install that fallback.
Source
Thrown at oap-server/server-admin/runtime-rule/src/main/java/org/apache/skywalking/oap/server/receiver/runtimerule/apply/MalShapeExtractor.java:128
/**
* Parse a MAL YAML file and return a map {@code metricName → shape}, where metric names
* follow the same {@code metricPrefix + "_" + ruleName} formula {@code MetricConvert} uses.
*
* <p>Returns an empty map when the YAML is null/empty or has no {@code metricsRules}. Any
* rule whose expression fails to parse is dropped from the result — the classifier treats
* "missing shape" conservatively (falls back to the STRUCTURAL-with-over-approximation
* path it already has).
*/
public static Map<String, MalShape> extract(final String yamlContent) {
if (yamlContent == null || yamlContent.isEmpty()) {
return Collections.emptyMap();
}
final Rule rule;
try (StringReader r = new StringReader(yamlContent)) {
rule = new Yaml().loadAs(r, Rule.class);
} catch (final Throwable t) {
throw new IllegalArgumentException("MAL YAML parse failure: " + t.getMessage(), t);
}
if (rule == null || rule.getMetricsRules() == null || rule.getMetricPrefix() == null) {
return Collections.emptyMap();
}
final Map<String, MalShape> out = new LinkedHashMap<>();
for (final MetricsRule mr : rule.getMetricsRules()) {
if (mr.getName() == null) {
continue;
}
final String metricName = rule.getMetricPrefix() + "_" + mr.getName();
final String fullExpr = formatExp(rule.getExpPrefix(), rule.getExpSuffix(), mr.getExp());
final MalShape shape = extractShape(fullExpr);
if (shape != null) {
out.put(metricName, shape);
}
}
return Collections.unmodifiableMap(out);
}View on GitHub (pinned to 102af09b4a)
Solutions
- If you call extract directly, wrap it and treat failure as 'unknown shape' (empty map) — matching the documented conservative contract the classifier already uses
- Repair the malformed prior/new content using the wrapped cause's YAML mark
- Validate content parses as Rule with metricPrefix before feeding shape extraction
- In tests, build prior content via the same serializer the runtime uses instead of hand-written strings
Example fix
// before
Map<String, MalShape> shapes = MalShapeExtractor.extract(priorContent);
// after — honor the conservative-fallback contract
Map<String, MalShape> shapes;
try {
shapes = MalShapeExtractor.extract(priorContent);
} catch (final IllegalArgumentException e) {
shapes = Collections.emptyMap(); // unknown shape -> STRUCTURAL over-approximation
} Defensive patterns
Strategy: fallback
Validate before calling
try (StringReader r = new StringReader(content)) { new Yaml().loadAs(r, Rule.class); } // if this throws, extract() will throw too Try / catch
catch (IllegalArgumentException e) when 'MAL YAML parse failure': return Collections.emptyMap() (unknown shape) and let the classifier take the conservative STRUCTURAL path — this mirrors the documented contract; log at WARN for traceability.
Prevention
- Never call MalShapeExtractor without the empty-map fallback — it is designed to be defeatable
- Keep prior-content strings sourced from the real store, not hand-typed fixtures
- In migrations, re-serialize old rules through the standard parser before classification
When it happens
Trigger: Invoking MalShapeExtractor.extract on content that is not parseable as a MAL Rule — bad YAML, LAL-flavored document, or truncated body. Note: null/empty input returns an empty map, and a parsed rule lacking metricPrefix/metricsRules also returns empty; only an actual parse throw raises this error.
Common situations: DeltaClassifier running classifyMal on prior content that was corrupted in storage; Feeding a manually assembled prior-content string (tests, migration scripts) that isn't valid MAL YAML; Calling extract directly from tooling without a try/catch
Related errors
- Load rule {} failed
- YAML parsed to null — empty or malformed rule file: {sourceN
- YAML parse failure for {sourceName}
- Load meter analyzer configs failed
- Unsupported extractor statement in LAL rule at line {sourceL
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/ce55c454742f1a89.
Report an issue: GitHub.