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
- Run the left operand alone and confirm exactly one value is returned
- Force scalar semantics with sum()/avg()/latest() on the left operand
- 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
- 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
- Keep the scalar on a consistent side in your query templates
- Verify nested parenthesized scalars return one value before combining with series
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
- Single to Single, left result is empty or has more than one
- 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
- 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/e1f7ca75950ade7b.
Report an issue: GitHub.