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

  1. If you call extract directly, wrap it and treat failure as 'unknown shape' (empty map) — matching the documented conservative contract the classifier already uses
  2. Repair the malformed prior/new content using the wrapped cause's YAML mark
  3. Validate content parses as Rule with metricPrefix before feeding shape extraction
  4. 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

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


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/ce55c454742f1a89. Report an issue: GitHub.