apache/skywalking · error · IllegalExpressionException

Many to One, single result is empty or has more than one val

Error message

Many to One, single result is empty or has more than one value.

What it means

Thrown by LROp.many2OneBinaryOp, used when a collection-typed operand (TIME_SERIES_VALUES, SORTED_LIST, RECORD_LIST, or a labeled SINGLE_VALUE via single2SingleBinaryOp) is combined with a scalar. The SCALAR side (here the right/single operand) must have exactly one result with exactly one value; otherwise the operation is undefined.

Source

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

                if (valueL.isEmptyValue() || valueR.isEmptyValue()) {
                    valueL.setEmptyValue(true);
                    continue;
                }
                double value = calculate.apply(valueL.getDoubleValue(), valueR.getDoubleValue(), opType);
                valueL.setDoubleValue(value);
            }
        }

        return singleLeft;
    }

    //series or list or labeled single value with scalar
    private static ExpressionResult many2OneBinaryOp(ExpressionResult manyResult,
                                                     ExpressionResult singleResult,
                                                     int opType, LROp calculate) throws IllegalExpressionException {
        if (singleResult.getResults().isEmpty() ||
            singleResult.getResults().get(0).getValues().size() != 1) {
            throw new IllegalExpressionException("Many to One, single result is empty or has more than one value.");
        }
        for (MQEValues mqeValues : manyResult.getResults()) {
            for (MQEValue mqeValue : mqeValues.getValues()) {
                if (!mqeValue.isEmptyValue()) {
                    double newValue = calculate.apply(
                        mqeValue.getDoubleValue(), singleResult.getResults()
                                                               .get(0)
                                                               .getValues()
                                                               .get(0)
                                                               .getDoubleValue(), opType);
                    mqeValue.setDoubleValue(newValue);
                }
            }
        }
        return manyResult;
    }

    //scalar with series or list or labeled single value

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Run the scalar (right) operand alone and verify it returns exactly one value
  2. Wrap the scalar operand in an aggregation or latest() to force a single value
  3. If the scalar may be empty, restructure the query to avoid the binary op when data is missing
  4. Check nested parentheses: make sure the single-value side is the one you intend, not a series

Example fix

// before
query: service_resp_time + (sum(other) / sum(total))  // parenthesized scalar empty
// after
query: service_resp_time + latest(other_total_ratio)
Defensive patterns

Strategy: validation

Validate before calling

ExpressionResult scalar = mqeService.eval(scalarExpr);
boolean ok = !scalar.getResults().isEmpty()
    && scalar.getResults().get(0).getValues().size() == 1;

Try / catch

catch (IllegalExpressionException e) { /* message says 'Many to One, single result...' — audit the scalar side */ }

Prevention

When it happens

Trigger: MQE expression like 'time_series_metric + 100' fails only if the scalar side's results are empty or its first MQEValues has != 1 values — a plain literal is fine, so in practice this is a computed scalar (nested aggregation, parenthesized expression, relabeled scalar) that is empty or multi-valued.

Common situations: The scalar operand is a sub-query returning no data in the time range; a nested expression on the scalar side producing multiple values; a labeled scalar routed through single2SingleBinaryOp into many2OneBinaryOp with a malformed group; version changes altering nested expression result shapes.

Related errors


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