apache/skywalking · error · IllegalExpressionException

Series No Labeled with Labeled, no labeled result is empty.

Error message

Series No Labeled with Labeled, no labeled result is empty.

What it means

Thrown by LROp.seriesNoLabeledWithLabeled when a NON-labeled series is combined with a labeled series: the left (non-labeled) side's results must not be empty, since its single series is used as the base that gets rewritten per right label group (note the result writes into mqeValuesR but returns seriesLeft).

Source

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

                MQEValue valueL = mqeValuesL.getValues().get(i);
                MQEValue valueR = mqeValuesR.getValues().get(i);
                if (valueL.isEmptyValue() || valueR.isEmptyValue()) {
                    valueL.setEmptyValue(true);
                    continue;
                }
                double newValue = calculate.apply(valueL.getDoubleValue(), valueR.getDoubleValue(), opType);
                mqeValuesL.getValues().get(i).setDoubleValue(newValue);
            }
        }

        return seriesLeft;
    }

    private static ExpressionResult seriesNoLabeledWithLabeled(ExpressionResult seriesLeft,
                                                               ExpressionResult seriesRight,
                                                               int opType, LROp calculate) throws IllegalExpressionException {
        if (seriesLeft.getResults().isEmpty()) {
            throw new IllegalExpressionException("Series No Labeled with Labeled, no labeled result is empty.");
        }
        MQEValues mqeValuesL = seriesLeft.getResults().get(0);
        for (MQEValues mqeValuesR : seriesRight.getResults()) {
            if (mqeValuesL.getValues().size() != mqeValuesR.getValues().size()) {
                throw new IllegalExpressionException("Series No Labeled with Labeled, left and right series value size not equal.");
            }
            for (int i = 0; i < mqeValuesL.getValues().size(); i++) {
                //reserve left metric info
                MQEValue valueL = mqeValuesL.getValues().get(i);
                MQEValue valueR = mqeValuesR.getValues().get(i);
                if (valueL.isEmptyValue() || valueR.isEmptyValue()) {
                    valueL.setEmptyValue(true);
                    continue;
                }
                double newValue = calculate.apply(valueL.getDoubleValue(), valueR.getDoubleValue(), opType);
                mqeValuesR.getValues().get(i).setDoubleValue(newValue);
            }
        }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Run the plain left operand alone and confirm it returns a series
  2. Ensure both metrics share the time range and step
  3. If the empty side is expected, swap to viewAsSeq or guard the query
  4. Verify the left metric is still being collected (agent config, MAL/OAL rules intact)

Example fix

// before
query: b - relabels(a, tag:(k,v))   // b empty
// after: use a window where b has data, or
query: viewAsSeq(b, relabels(a, tag:(k,v)))
Defensive patterns

Strategy: validation

Validate before calling

boolean ok = !seriesLeft.getResults().isEmpty(); // the non-labeled LEFT side

Try / catch

catch (IllegalExpressionException e) { surfaceQueryError(e); }

Prevention

When it happens

Trigger: MQE expression 'plainSeries op labeledSeries' (e.g. 'b - relabels(a, ...)') where the plain LEFT operand returns zero results. The check only guards seriesLeft; the labeled right side is iterated per group.

Common situations: The unlabeled metric has no data in the queried window while the labeled one does; operator ordering flipped during query refactoring so the empty metric ended up on the left; metric renamed or disabled leaving the left side empty.

Related errors


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