apache/skywalking · error · IllegalArgumentException

Unsupported step: {}

Error message

Unsupported step: {}

What it means

TrendOp.calculateRate divides increase values by a range in seconds derived from the query Step; only SECOND, MINUTE, HOUR and DAY are handled. Any other Step constant hits the default branch and throws IllegalArgumentException (note: NOT IllegalExpressionException — a plain runtime exception, and the message is built by string concatenation, matching '{}'-style formatting only loosely).

Source

Thrown at oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/TrendOp.java:94

    private static ExpressionResult calculateRate(ExpressionResult expResult, int trendRange, Step step) {
        ExpressionResult result = calculateIncrease(expResult, trendRange);
        long rangeSeconds;
        switch (step) {
            case SECOND:
                rangeSeconds = trendRange;
                break;
            case MINUTE:
                rangeSeconds = trendRange * 60;
                break;
            case HOUR:
                rangeSeconds = trendRange * 3600;
                break;
            case DAY:
                rangeSeconds = trendRange * 86400;
                break;
            default:
                throw new IllegalArgumentException("Unsupported step: " + step);
        }
        result.getResults().forEach(resultValues -> {
            resultValues.getValues().forEach(mqeValue -> {
                if (!mqeValue.isEmptyValue()) {
                    double newValue = mqeValue.getDoubleValue() / rangeSeconds;
                    mqeValue.setDoubleValue(newValue);
                }
            });
        });
        return result;
    }
}

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Query with a standard step (SECOND, MINUTE, HOUR, or DAY) via the normal metrics query API
  2. If a new Step constant is required, add its case (seconds multiplier) to the switch in TrendOp.calculateRate and rebuild mqe-rt
  3. Ensure the whole OAP server (server-core and mqe-rt) is deployed as one coherent version
  4. When calling MQE evaluation programmatically, always set an explicit valid Step on the query context

Example fix

// before
// internal evaluation with a placeholder/custom step
step = Step.WEEK; // no case in TrendOp -> IllegalArgumentException
// after
step = Step.DAY;
Defensive patterns

Strategy: validation

Validate before calling

if (step != Step.SECOND && step != Step.MINUTE && step != Step.HOUR && step != Step.DAY) {
    throw new IllegalArgumentException("Step must be SECOND/MINUTE/HOUR/DAY for rate()");
}

Type guard

boolean isRateSupportedStep(Step s) {
    return s == Step.SECOND || s == Step.MINUTE || s == Step.HOUR || s == Step.DAY;
}

Try / catch

catch (IllegalArgumentException e) { /* note: NOT IllegalExpressionException — this one escapes the MQE error channel; guard the step up front */ }

Prevention

When it happens

Trigger: Calling rate(metric, range) when the query's Step resolves to something outside SECOND/MINUTE/HOUR/DAY — e.g. a new Step enum constant added to server-core without updating TrendOp, or programmatic MQE evaluation with a custom/placeholder Step.

Common situations: OAP version skew where Step gained new constants (e.g. a week-level step) but mqe-rt predates it; custom code invoking the rate evaluation path with an uninitialized Step; queries constructed via internal APIs rather than the GraphQL query API which normalizes step.

Related errors


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