apache/skywalking · error · IllegalExpressionException
Single to Single, left result is empty or has more than one
Error message
Single to Single, left result is empty or has more than one value.
What it means
Thrown by LROp.single2SingleNoLabeled when a binary arithmetic operation (+, -, *, /, ...) is applied to two SINGLE_VALUE operands but the LEFT operand's results list is empty, or its first MQEValues holds a number of values other than exactly 1. The MQE runtime models a scalar as exactly one MQEValues with exactly one MQEValue; anything else is not a valid scalar and the operation refuses to guess which value to use.
Source
Thrown at oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/LROp.java:97
ExpressionResult singleRight,
int opType, LROp calculate) throws IllegalExpressionException {
if (!singleLeft.isLabeledResult() && !singleRight.isLabeledResult()) { // no labeled with no labeled
return single2SingleNoLabeled(singleLeft, singleRight, opType, calculate);
} else if (singleLeft.isLabeledResult() && !singleRight.isLabeledResult()) { // labeled with no labeled
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()) {View on GitHub (pinned to 102af09b4a)
Solutions
- Verify the left operand of the binary expression actually returns exactly one value, e.g. run the left side alone as an MQE query and inspect results[0].values length
- Wrap the left operand in an aggregation that guarantees a single value, such as sum(metricA) or avg(metricA), instead of using the raw metric
- If the left operand is empty because no data exists yet, guard the expression or accept the IllegalExpressionException as the documented empty-input signal
- Check for label manipulation (relabels/onLabel) on the left metric that changed its result shape from scalar to labeled, and adjust which side carries the labels
Example fix
// before query: service_sla / service_cpm // after (force single values on both sides) query: sum(service_sla) / sum(service_cpm)
Defensive patterns
Strategy: validation
Validate before calling
ExpressionResult left = mqeService.eval(leftExpr);
boolean ok = left.getResults().size() == 1
&& left.getResults().get(0).getValues().size() == 1
&& left.getType() == ExpressionResultType.SINGLE_VALUE
&& !left.getResults().get(0).getValues().get(0).isEmptyValue(); Try / catch
catch (IllegalExpressionException e) { /* surface e.getMessage() to the query client; message names the offending side */ } Prevention
- Always aggregate raw metrics (sum/avg/latest) before using them as scalar operands
- Run each operand alone first when composing a new MQE binary expression
- Treat empty results on a scalar operand as a data-availability problem, not a syntax problem
When it happens
Trigger: An MQE expression like 'metricA / metricB' (or scalar op scalar) where the left sub-expression was typed SINGLE_VALUE (e.g. produced by aggregation like sum(), or a literal) but its results collection is empty or contains multiple values. This path is only reached when NEITHER side is a labeled result (single2SingleBinaryOp, LROp.java:81-82).
Common situations: A metric query returns no data for the left operand (empty results) while its type is still SINGLE_VALUE; mixing a scalar metric with a relabeled/labeled metric so the type detection misclassifies it; upgrading OAP versions where a metric's expression result shape changed; querying a metric name that exists in the schema but has never received data.
Related errors
- Single to Single, right result is empty or has more than one
- Many to One, single result is empty or has more than one val
- One to Many, single result is empty or has more than one val
- Single Labeled to Single Labeled, left labeled result is emp
- Single Labeled to Single Labeled, right labeled result has m
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/ef2a2368591cc6fd.
Report an issue: GitHub.