{"record":{"id":"32cbc13b32f5734a","repo":"apache/skywalking","slug":"single-to-single-right-result-is-empty-or-has-mor","errorCode":null,"errorMessage":"Single to Single, right result is empty or has more than one value.","messagePattern":"Single to Single, right result is empty or has more than one value\\.","errorType":"exception","errorClass":"IllegalExpressionException","httpStatus":null,"severity":"error","filePath":"oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/LROp.java","lineNumber":102,"sourceCode":"            return many2OneBinaryOp(singleLeft, singleRight, opType, calculate);\n        } else if (!singleLeft.isLabeledResult() && singleRight.isLabeledResult()) { // no labeled with labeled\n            return one2ManyBinaryOp(singleLeft, singleRight, opType, calculate);\n        } else { // labeled with labeled\n            return single2SingleLabeled(singleLeft, singleRight, opType, calculate);\n        }\n    }\n\n    private static ExpressionResult single2SingleNoLabeled(ExpressionResult singleLeft,\n                                                          ExpressionResult singleRight,\n                                                          int opType, LROp calculate) throws IllegalExpressionException {\n        if (singleLeft.getResults().isEmpty() ||\n            singleLeft.getResults().get(0).getValues().size() != 1) {\n            throw new IllegalExpressionException(\"Single to Single, left result is empty or has more than one value.\");\n        }\n\n        if (singleRight.getResults().isEmpty() ||\n            singleRight.getResults().get(0).getValues().size() != 1) {\n            throw new IllegalExpressionException(\"Single to Single, right result is empty or has more than one value.\");\n        }\n\n        ExpressionResult result = new ExpressionResult();\n        MQEValue mqeValue = new MQEValue();\n        MQEValues mqeValues = new MQEValues();\n        mqeValues.getValues().add(mqeValue);\n        result.getResults().add(mqeValues);\n        result.setType(ExpressionResultType.SINGLE_VALUE);\n\n        MQEValue left = singleLeft.getResults().get(0).getValues().get(0);\n        MQEValue right = singleRight.getResults().get(0).getValues().get(0);\n        //return null if one of them is empty\n        if (left.isEmptyValue() || right.isEmptyValue()) {\n            mqeValue.setEmptyValue(true);\n        } else {\n            double value = calculate.apply(left.getDoubleValue(), right.getDoubleValue(), opType);\n            mqeValue.setDoubleValue(value);\n        }","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/LROp.java#L84-L120","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Run the right operand alone as an MQE query and confirm it returns exactly one non-empty value","Wrap the right operand in an aggregation function (sum/avg/latest) to collapse it to a single value","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","Verify the right operand is not actually a labeled or series metric misused as a scalar"],"exampleFix":"// before\nquery: sum(a) / b\n// after\nquery: sum(a) / sum(b)","handlingStrategy":"validation","validationCode":"ExpressionResult right = mqeService.eval(rightExpr);\nboolean ok = right.getResults().size() == 1\n    && right.getResults().get(0).getValues().size() == 1;","typeGuard":null,"tryCatchPattern":"catch (IllegalExpressionException e) { return badRequest(e.getMessage()); }","preventionTips":["Validate the denominator/right operand returns exactly one value before dividing","Prefer aggregation wrappers over raw metrics on both sides of scalar ops","Check data presence in the target time range before issuing combined expressions"],"tags":["mqe","query-engine","metrics","binary-op"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}