apache/skywalking · error · IllegalExpressionException

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

Error message

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

What it means

Thrown by LROp.one2ManyBinaryOp — the mirror of many2One — when a scalar is combined with a collection (series/list/record-list or labeled single). Here the LEFT operand is the scalar and must be exactly one result with one value; if it is empty or multi-valued the exception fires.

Source

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

                        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
    private static ExpressionResult one2ManyBinaryOp(ExpressionResult singleResult,
                                                     ExpressionResult manyResult,
                                                     int opType, LROp calculate) throws IllegalExpressionException {
        if (singleResult.getResults().isEmpty() ||
            singleResult.getResults().get(0).getValues().size() != 1) {
            throw new IllegalExpressionException("One to Many, 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(
                        singleResult.getResults()
                                    .get(0)
                                    .getValues()
                                    .get(0)
                                    .getDoubleValue(),
                        mqeValue.getDoubleValue(), opType
                    );
                    mqeValue.setDoubleValue(newValue);
                }
            }
        }
        return manyResult;
    }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Run the left operand alone and confirm exactly one value is returned
  2. Force scalar semantics with sum()/avg()/latest() on the left operand
  3. Swap operands if the intent was series-op-scalar (many2One path) — though both paths validate the scalar equally, keeping the scalar on one side consistently makes queries easier to audit
  4. Avoid the binary op when the scalar side can legitimately be empty; use isPresent() or restructure

Example fix

// before
query: (a / b) * service_cpm   // a/b empty or multi-valued
// after
query: latest(a_b_ratio) * service_cpm
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) { surfaceQueryError(e); }

Prevention

When it happens

Trigger: MQE expression like '100 / time_series_metric' or 'scalar_expr * series' where the left scalar operand's results are empty or its first MQEValues holds != 1 values. Reached from doLROp when left is SINGLE_VALUE and right is TIME_SERIES_VALUES/SORTED_LIST/RECORD_LIST, or from single2SingleBinaryOp when only the right side is labeled.

Common situations: Left scalar sub-query with no data in range; a computed scalar (ratio, aggregation) returning multiple values; putting the series on the wrong side of the operator after refactoring a query; a labeled right metric changing the dispatch to this branch unexpectedly.

Related errors


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