{"record":{"id":"e1f7ca75950ade7b","repo":"apache/skywalking","slug":"one-to-many-single-result-is-empty-or-has-more-th","errorCode":null,"errorMessage":"One to Many, single result is empty or has more than one value.","messagePattern":"One to Many, single 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":187,"sourceCode":"                        mqeValue.getDoubleValue(), singleResult.getResults()\n                                                               .get(0)\n                                                               .getValues()\n                                                               .get(0)\n                                                               .getDoubleValue(), opType);\n                    mqeValue.setDoubleValue(newValue);\n                }\n            }\n        }\n        return manyResult;\n    }\n\n    //scalar with series or list or labeled single value\n    private static ExpressionResult one2ManyBinaryOp(ExpressionResult singleResult,\n                                                     ExpressionResult manyResult,\n                                                     int opType, LROp calculate) throws IllegalExpressionException {\n        if (singleResult.getResults().isEmpty() ||\n            singleResult.getResults().get(0).getValues().size() != 1) {\n            throw new IllegalExpressionException(\"One to Many, single result is empty or has more than one value.\");\n        }\n        for (MQEValues mqeValues : manyResult.getResults()) {\n            for (MQEValue mqeValue : mqeValues.getValues()) {\n                if (!mqeValue.isEmptyValue()) {\n                    double newValue = calculate.apply(\n                        singleResult.getResults()\n                                    .get(0)\n                                    .getValues()\n                                    .get(0)\n                                    .getDoubleValue(),\n                        mqeValue.getDoubleValue(), opType\n                    );\n                    mqeValue.setDoubleValue(newValue);\n                }\n            }\n        }\n        return manyResult;\n    }","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/LROp.java#L169-L205","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nquery: (a / b) * service_cpm   // a/b empty or multi-valued\n// after\nquery: latest(a_b_ratio) * service_cpm","handlingStrategy":"validation","validationCode":"ExpressionResult scalar = mqeService.eval(scalarExpr);\nboolean ok = !scalar.getResults().isEmpty()\n    && scalar.getResults().get(0).getValues().size() == 1;","typeGuard":null,"tryCatchPattern":"catch (IllegalExpressionException e) { surfaceQueryError(e); }","preventionTips":["Keep the scalar on a consistent side in your query templates","Verify nested parenthesized scalars return one value before combining with series"],"tags":["mqe","query-engine","metrics","binary-op"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}