apache/skywalking · error · IllegalArgumentException

Unsupported enum operator: {}

Error message

Unsupported enum operator: {}

What it means

Thrown while mapping an enum-valued OAL filter to a matcher type. Enum comparisons are lowered to string matching, and only EQUAL and NOT_EQUAL are supported; any other operator against an enum constant falls to default.

Source

Thrown at oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/v2/generator/MetricDefinitionEnricher.java:493

        } else if (value.isString()) {
            switch (op) {
                case EQUAL: return "stringMatch";
                case NOT_EQUAL: return "notEqualMatch";
                case LIKE: return "likeMatch";
                case CONTAIN: return "containMatch";
                case NOT_CONTAIN: return "notContainMatch";
                default: throw new IllegalArgumentException("Unsupported string operator: " + op);
            }
        } else if (value.isArray()) {
            return "inMatch";
        } else if (value.isNull()) {
            return op == FilterOperator.EQUAL ? "stringMatch" : "notEqualMatch";
        } else if (value.isEnum()) {
            // Enum comparisons use string matching (e.g., type == RequestType.MQ)
            switch (op) {
                case EQUAL: return "stringMatch";
                case NOT_EQUAL: return "notEqualMatch";
                default: throw new IllegalArgumentException("Unsupported enum operator: " + op);
            }
        }

        throw new IllegalArgumentException("Unsupported filter: " + filterExpr);
    }

    /**
     * Collect persistent fields from metrics class @Column annotations.
     */
    private List<CodeGenModel.DataFieldV2> collectPersistentFields(Class<? extends Metrics> metricsClass) {
        List<CodeGenModel.DataFieldV2> persistentFields = new ArrayList<>();
        Class<?> c = metricsClass;
        while (!c.equals(Object.class)) {
            for (Field field : c.getDeclaredFields()) {
                Column column = field.getAnnotation(Column.class);
                if (column != null) {
                    persistentFields.add(CodeGenModel.DataFieldV2.builder()
                        .fieldName(field.getName())

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Use only equality or inequality against enum constants: type = RequestType.MQ or type != RequestType.MQ
  2. If richer matching is needed, filter on the corresponding string attribute instead of the enum

Example fix

// before (OAL)
mqSpans = from Span where type like RequestType.MQ --> mqSpans
// after
mqSpans = from Span where type = RequestType.MQ --> mqSpans
Defensive patterns

Strategy: validation

Validate before calling

// Lint rule: enum value + non-equality operator => reject before deploy
if (value.isEnum() && op != EQUAL && op != NOT_EQUAL) {
    throw new ConfigException("Enum filter supports only = and !=, got " + op);
}

Try / catch

In OAL lint tooling, catch IllegalArgumentException from the enricher and report file:line of the offending rule; never blanket-catch in OAP startup.

Prevention

When it happens

Trigger: An OAL rule uses an ordering or substring operator against an enum constant, e.g. from X where type like RequestType.MQ or type > RequestType.HTTP. The enum branch only accepts = and !=.

Common situations: Filtering span/request type enums with operators copied from string filters; adding new enum-attribute sources and reusing an old filter line unchanged.

Related errors


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