{"record":{"id":"6af5705c6597142c","repo":"apache/skywalking","slug":"unsupported-sort-order","errorCode":null,"errorMessage":"Unsupported sort order.","messagePattern":"Unsupported sort order\\.","errorType":"exception","errorClass":"IllegalExpressionException","httpStatus":null,"severity":"error","filePath":"oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/SortLabelValuesOp.java","lineNumber":50,"sourceCode":"\nimport static java.util.stream.Collectors.groupingBy;\nimport static java.util.stream.Collectors.toList;\n\n@Slf4j\npublic class SortLabelValuesOp {\n    public static ExpressionResult doSortLabelValuesOp(ExpressionResult expResult,\n                                                      int order,\n                                                      List<String> labelNames) throws IllegalExpressionException {\n        if (CollectionUtils.isNotEmpty(labelNames)) {\n            labelNames = labelNames.stream().distinct().collect(toList());\n            if (MQEParser.ASC == order) {\n                expResult.setResults(\n                    sort(expResult.getResults(), labelNames, labelNames.get(0), Comparator.naturalOrder()));\n            } else if (MQEParser.DES == order) {\n                expResult.setResults(\n                    sort(expResult.getResults(), labelNames, labelNames.get(0), Comparator.reverseOrder()));\n            } else {\n                throw new IllegalExpressionException(\"Unsupported sort order.\");\n            }\n        }\n        return expResult;\n    }\n\n    private static List<MQEValues> sort(List<MQEValues> results,\n                                        List<String> sortLabels,\n                                        String currentSortLabel,\n                                        Comparator<String> comparator) {\n        if (!sortLabels.contains(currentSortLabel)) {\n            log.error(\"Current sort label {} not found in the sort labels {} \", currentSortLabel, sortLabels);\n            return results;\n        }\n        if (sortLabels.indexOf(\n            currentSortLabel) == sortLabels.size() - 1) { //only one label or the latest label no need to group\n            results.sort(Comparator.comparing(mqeValues -> mqeValues.getMetric()\n                                                                    .getLabels()\n                                                                    .stream()","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/apache/skywalking/blob/102af09b4a56064e22050dded10e2c52e490d040/oap-server/mqe-rt/src/main/java/org/apache/skywalking/mqe/rt/operation/SortLabelValuesOp.java#L32-L68","documentation":"SortLabelValuesOp.doSortLabelValuesOp sorts labeled results by label values; the order token must be exactly MQEParser.ASC or MQEParser.DES. Any other integer reaching the else branch throws 'Unsupported sort order.'. This op backs the sortLabelsForLabeledValues(...) MQE construct; a well-formed parse yields ASC or DES, so other values indicate grammar/runtime mismatch or direct API misuse.","triggerScenarios":"Calling sortLabelsForLabeledValues with an order argument that is neither the ASC nor DES token constant — e.g. passing a SQL-style 'asc'/'desc' string mapping, 0/1 ints, or a custom grammar token after a fork; or a visitor bug passing the wrong token type.","commonSituations":"Custom grammar forks adding a new sort direction; calling the mqe-rt operation classes directly from plugin code with hand-built opType constants; version skew between the generated parser and the runtime operations jar.","solutions":["Use the documented MQE syntax: sortLabelsForLabeledValues(metric, ASC, labelNames) or DES","If calling programmatically, pass MQEParser.ASC or MQEParser.DES exactly, sourced from the same generated parser version as mqe-rt","For new sort-order tokens in a fork, add an else-if branch in doSortLabelValuesOp","Ensure mqe-grammar and mqe-rt jars match versions"],"exampleFix":"// before\nSortLabelValuesOp.doSortLabelValuesOp(result, 0, labels);  // 0 is neither ASC nor DES\n// after\nSortLabelValuesOp.doSortLabelValuesOp(result, MQEParser.ASC, labels);","handlingStrategy":"validation","validationCode":"if (order != MQEParser.ASC && order != MQEParser.DES) {\n    throw new IllegalArgumentException(\"order must be MQEParser.ASC or MQEParser.DES\");\n}","typeGuard":"boolean isValidSortOrder(int order) { return order == MQEParser.ASC || order == MQEParser.DES; }","tryCatchPattern":"catch (IllegalExpressionException e) { /* bad sort order constant passed to sortLabelsForLabeledValues */ }","preventionTips":["Use the documented ASC/DES tokens in sortLabelsForLabeledValues","Import token constants from the same generated parser version as the runtime"],"tags":["mqe","query-engine","sort","unsupported-operation"],"backgroundTag":null,"analyzedSha":"102af09b4a56064e22050dded10e2c52e490d040","analyzedAt":"2026-08-14T10:47:52.647Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}