{"record":{"id":"b8a07371229c9179","repo":"apache/druid","slug":"no-order-s-for-column-s","errorCode":null,"errorMessage":"No order[%s] for column[%s]","messagePattern":"No order\\[(.+?)\\] for column\\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"warning","filePath":"processing/src/main/java/org/apache/druid/query/OrderBy.java","lineNumber":87,"sourceCode":"    return order;\n  }\n\n  /**\n   * Returns true if the given {@link OrderBy} is the exact reverse, meaning they have the same column name\n   * in revrersed order.\n   */\n  public boolean isExactReverse(OrderBy that)\n  {\n    if (!columnName.equals(that.columnName)) {\n      return false;\n    }\n    switch (order) {\n      case ASCENDING:\n        return Order.DESCENDING.equals(that.order);\n      case DESCENDING:\n        return Order.ASCENDING.equals(that.order);\n      default:\n        throw new IAE(\"No order[%s] for column[%s]\", order, columnName);\n    }\n  }\n\n  @Override\n  public boolean equals(Object o)\n  {\n    if (this == o) {\n      return true;\n    }\n    if (o == null || getClass() != o.getClass()) {\n      return false;\n    }\n    OrderBy that = (OrderBy) o;\n    return Objects.equals(columnName, that.columnName) && order == that.order;\n  }\n\n  @Override\n  public int hashCode()","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/query/OrderBy.java#L69-L105","documentation":"OrderBy.isExactReverse checks whether another OrderBy has the opposite direction on the same column. Its switch handles ASCENDING and DESCENDING; since the constructor forbids Order.NONE, reaching the default branch indicates an unexpected order value, and this defensive IllegalArgumentException is thrown.","triggerScenarios":"Calling isExactReverse on an OrderBy whose order is Order.NONE (only possible via deserialization paths that bypass the constructor validation, or a newly added Order enum constant).","commonSituations":"Comparing sort specs built from deserialized query JSON where order was null/NONE; adding a new Order enum value without updating isExactReverse; reflection-built OrderBy objects.","solutions":["Ensure the OrderBy object has ASCENDING or DESCENDING before calling isExactReverse.","If a new Order constant was added, add a case for it in isExactReverse.","Fix deserialization/creation paths that allow Order.NONE despite the constructor check."],"exampleFix":"// before\nif (orderBy.isExactReverse(other)) { ... } // orderBy.order == NONE\n// after\nif (orderBy.getOrder() != Order.NONE && orderBy.isExactReverse(other)) { ... }","handlingStrategy":"validation","validationCode":"if (order == Order.NONE) { throw new IllegalArgumentException(\"Cannot compare NONE order\"); }","typeGuard":"boolean isDirectional(OrderBy o) { return o.getOrder() != Order.NONE; }","tryCatchPattern":"try {\n  boolean reverse = a.isExactReverse(b);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"No order\")) { reverse = false; }\n  else { throw e; }\n}","preventionTips":["Guarantee OrderBy instances have ASCENDING/DESCENDING before comparisons.","Update switch statements when adding new Order enum constants.","Avoid deserialization paths that bypass OrderBy constructor validation."],"tags":["sorting","internal-invariant-violation","enum"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}