apache/skywalking · error · IllegalExpressionException

Single to Single, right result is empty or has more than one

Error message

Single to Single, right result is empty or has more than one value.

What it means

Mirror of the left-side check in LROp.single2SingleNoLabeled: a scalar-to-scalar binary operation where the RIGHT operand is typed SINGLE_VALUE but has an empty results list, or its first MQEValues contains more than one value. The right operand must be exactly one value for the calculation to be well-defined.

Source

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

            return many2OneBinaryOp(singleLeft, singleRight, opType, calculate);
        } else if (!singleLeft.isLabeledResult() && singleRight.isLabeledResult()) { // no labeled with labeled
            return one2ManyBinaryOp(singleLeft, singleRight, opType, calculate);
        } else { // labeled with labeled
            return single2SingleLabeled(singleLeft, singleRight, opType, calculate);
        }
    }

    private static ExpressionResult single2SingleNoLabeled(ExpressionResult singleLeft,
                                                          ExpressionResult singleRight,
                                                          int opType, LROp calculate) throws IllegalExpressionException {
        if (singleLeft.getResults().isEmpty() ||
            singleLeft.getResults().get(0).getValues().size() != 1) {
            throw new IllegalExpressionException("Single to Single, left result is empty or has more than one value.");
        }

        if (singleRight.getResults().isEmpty() ||
            singleRight.getResults().get(0).getValues().size() != 1) {
            throw new IllegalExpressionException("Single to Single, right result is empty or has more than one value.");
        }

        ExpressionResult result = new ExpressionResult();
        MQEValue mqeValue = new MQEValue();
        MQEValues mqeValues = new MQEValues();
        mqeValues.getValues().add(mqeValue);
        result.getResults().add(mqeValues);
        result.setType(ExpressionResultType.SINGLE_VALUE);

        MQEValue left = singleLeft.getResults().get(0).getValues().get(0);
        MQEValue right = singleRight.getResults().get(0).getValues().get(0);
        //return null if one of them is empty
        if (left.isEmptyValue() || right.isEmptyValue()) {
            mqeValue.setEmptyValue(true);
        } else {
            double value = calculate.apply(left.getDoubleValue(), right.getDoubleValue(), opType);
            mqeValue.setDoubleValue(value);
        }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Run the right operand alone as an MQE query and confirm it returns exactly one non-empty value
  2. Wrap the right operand in an aggregation function (sum/avg/latest) to collapse it to a single value
  3. If the right side may legitimately be empty, restructure the query so the empty case is handled (e.g. isPresent() check) rather than letting the arithmetic throw
  4. Verify the right operand is not actually a labeled or series metric misused as a scalar

Example fix

// before
query: sum(a) / b
// after
query: sum(a) / sum(b)
Defensive patterns

Strategy: validation

Validate before calling

ExpressionResult right = mqeService.eval(rightExpr);
boolean ok = right.getResults().size() == 1
    && right.getResults().get(0).getValues().size() == 1;

Try / catch

catch (IllegalExpressionException e) { return badRequest(e.getMessage()); }

Prevention

When it happens

Trigger: MQE binary expression with two SINGLE_VALUE, non-labeled operands where the right sub-expression yields zero or 2+ values, e.g. 'sum(a) / b' when b's results are empty or contain multiple MQEValue entries. Only reached when neither operand isLabeledResult().

Common situations: Right-hand metric has no data in the selected time range (empty results); dividing by a TopN or list-typed metric accidentally placed on the right side; relabels making the right side labeled which changes the dispatch branch; denominator metric disabled or renamed after a config change.

Related errors


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