apache/skywalking · error · IllegalExpressionException

Unsupported function.

Error message

Unsupported function.

What it means

TrendOp.doTrendOp implements trend functions over series: only increase(...) and rate(...) are dispatched. Any other opType reaching the end of the switch throws 'Unsupported function.' — again a defensive default, since the grammar should only route INCREASE and RATE here.

Source

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

import org.apache.skywalking.mqe.rt.exception.IllegalExpressionException;
import org.apache.skywalking.mqe.rt.grammar.MQEParser;
import org.apache.skywalking.oap.server.core.query.mqe.ExpressionResult;
import org.apache.skywalking.oap.server.core.query.mqe.MQEValue;
import org.apache.skywalking.oap.server.core.query.enumeration.Step;

public class TrendOp {
    public static ExpressionResult doTrendOp(ExpressionResult expResult,
                                             int opType,
                                             int trendRange,
                                             Step step) throws IllegalExpressionException {
        switch (opType) {
            case MQEParser.INCREASE:
                return TrendOp.calculateIncrease(expResult, trendRange);
            case MQEParser.RATE:
                return TrendOp.calculateRate(expResult, trendRange, step);
        }

        throw new IllegalExpressionException("Unsupported function.");
    }

    private static ExpressionResult calculateIncrease(ExpressionResult expResult, int trendRange) {
        expResult.getResults().forEach(resultValues -> {
            List<MQEValue> mqeValues = resultValues.getValues();
            List<MQEValue> newMqeValues = new ArrayList<>();
            for (int i = trendRange; i < mqeValues.size(); i++) {
                MQEValue mqeValue = mqeValues.get(i);
                //if the current value is empty, then the trend value is empty
                if (mqeValue.isEmptyValue()) {
                    newMqeValues.add(mqeValue);
                    continue;
                }
                MQEValue newMqeValue = new MQEValue();
                newMqeValue.setId(mqeValue.getId());

                //if the previous value is empty, then the trend value is empty
                if (mqeValues.get(i - trendRange).isEmptyValue()) {

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Use only increase(metric, range) and rate(metric, range) in MQE expressions
  2. For fork-added trend tokens, implement the case in doTrendOp and rebuild mqe-rt
  3. Deploy matching mqe-grammar and mqe-rt versions
  4. Check the MQE function reference for the supported trend functions in your OAP version

Example fix

// before
query: irate(metric, 5)  // unsupported trend function
// after
query: rate(metric, 5)
Defensive patterns

Strategy: try-catch

Validate before calling

Set<String> supportedTrend = Set.of("increase", "rate");

Try / catch

catch (IllegalExpressionException e) { /* unsupported trend token — use increase/rate or implement the case */ }

Prevention

When it happens

Trigger: A trend-function token other than increase/rate dispatched to doTrendOp — realistic only with a custom grammar fork (e.g. adding delta or irate) without a matching runtime case, or with mqe-grammar/mqe-rt version skew in the deployed jars.

Common situations: Forked OAP builds with new trend functions; partial upgrades leaving a stale mqe-rt jar; direct programmatic calls to TrendOp.doTrendOp with arbitrary opType constants.

Related errors


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