{"record":{"id":"966542e4b19f92b5","repo":"apache/skywalking","slug":"unsupported-binary-operation","errorCode":null,"errorMessage":"Unsupported binary operation: {}","messagePattern":"Unsupported binary operation: (.+?)","errorType":"exception","errorClass":"IllegalExpressionException","httpStatus":null,"severity":"error","filePath":"oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/BinaryOp.java","lineNumber":32,"sourceCode":" * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\npackage org.apache.skywalking.mqe.rt.operation;\n\nimport org.apache.skywalking.mqe.rt.exception.IllegalExpressionException;\nimport org.apache.skywalking.mqe.rt.grammar.MQEParser;\nimport org.apache.skywalking.oap.server.core.query.mqe.ExpressionResult;\n\npublic class BinaryOp {\n    public static ExpressionResult doBinaryOp(ExpressionResult left,\n                                              ExpressionResult right,\n                                              int opType) throws IllegalExpressionException {\n        try {\n            return LROp.doLROp(left, right, opType, BinaryOp::scalarBinaryOp);\n        } catch (IllegalExpressionException e) {\n            throw new IllegalExpressionException(\"Unsupported binary operation: \" + e.getMessage());\n        }\n    }\n\n    //scalar with scalar\n    private static double scalarBinaryOp(double leftValue, double rightValue, int opType) {\n        double calculatedResult = 0;\n        switch (opType) {\n            case MQEParser.ADD:\n                calculatedResult = leftValue + rightValue;\n                break;\n            case MQEParser.SUB:\n                calculatedResult = leftValue - rightValue;\n                break;\n            case MQEParser.MUL:\n                calculatedResult = leftValue * rightValue;\n                break;\n            case MQEParser.DIV:\n                calculatedResult = leftValue / rightValue;","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/BinaryOp.java#L14-L50","documentation":"IllegalExpressionException from BinaryOp.doBinaryOp: arithmetic binary operations (+, -, *, /, %) between two sub-results failed, and the message wraps the underlying reason from LROp — in practice 'Unsupported operation.' meaning the combination of ExpressionResultTypes on the left and right operands has no defined arithmetic rule in LROp's type matrix.","triggerScenarios":"MQE arithmetic between incompatible result shapes: e.g. a RECORD_LIST or SORTED_LIST operand combined with a series or another list (LROp supports single-with-single, many-with-one, one-with-many, series-with-series only), or labeled with no-labelled combinations whose intersection is empty for the chosen op.","commonSituations":"Adding a TopN/SORTED_LIST result to a scalar: 'topn(...) + 1'; mixing trace/log record queries into arithmetic; combining labeled and unlabeled series where the operation has no defined pairing.","solutions":["Read the wrapped message (e.getMessage() of the cause) — it is usually LROp's 'Unsupported operation.' indicating a type-combination problem","Restructure so both sides of the operator are the same shape: metric.sum(dt5m) + metric2.sum(dt5m), or wrap list results in an aggregation that reduces them to series/single values first","Apply arithmetic to the inner metric level rather than the outer list level: aggregate_labels(...) + scalar, not topn(...) + scalar","Verify with the MQE docs result-type matrix which operand pairs each operator accepts"],"exampleFix":"# before\ntopn(service_resp_time.sum(dt5m), 10, DES) + 1\n# after\ntopn((service_resp_time.sum(dt5m) + 1).sum(...), 10, DES)  # or compute on the series before topn","handlingStrategy":"type-guard","validationCode":"// Before combining: check both sides fit LROp's supported pairs\nboolean supportedPair(ExpressionResultType l, ExpressionResultType r) {\n    return (l == SINGLE_VALUE && r == SINGLE_VALUE)\n        || (isMany(l) && r == SINGLE_VALUE) || (l == SINGLE_VALUE && isMany(r))\n        || (l == TIME_SERIES_VALUES && r == TIME_SERIES_VALUES);\n}\nboolean isMany(ExpressionResultType t) { return t == TIME_SERIES_VALUES || t == SORTED_LIST || t == RECORD_LIST; }","typeGuard":"boolean isBinarySafe(org.apache.skywalking.oap.server.core.query.mqe.ExpressionResult r) {\n    ExpressionResultType t = r.getType();\n    return t == ExpressionResultType.SINGLE_VALUE || t == ExpressionResultType.TIME_SERIES_VALUES;\n}","tryCatchPattern":"catch (IllegalExpressionException e) { /* unwrap cause: usually 'Unsupported operation.' → reshape operands and rebuild the query */ }","preventionTips":["Keep both operands of +,-,*,/ as plain time-series or scalars","Reduce SORTED_LIST/RECORD_LIST results before arithmetic","Test sub-expressions individually in the UI before combining"],"tags":["mqe","arithmetic","type-mismatch","query","unsupported-operation"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}