{"record":{"id":"5d4a280c6aa81aa5","repo":"apache/iceberg","slug":"unable-to-parse-sortorder-s-5d4a28","errorCode":null,"errorMessage":"Unable to parse sortOrder: %s","messagePattern":"Unable to parse sortOrder: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/ExtendedParser.java","lineNumber":63,"sourceCode":"      return term;\n    }\n\n    public SortDirection direction() {\n      return direction;\n    }\n\n    public NullOrder nullOrder() {\n      return nullOrder;\n    }\n  }\n\n  static List<RawOrderField> parseSortOrder(SparkSession spark, String orderString) {\n    ExtendedParser extParser = findParser(spark.sessionState().sqlParser(), ExtendedParser.class);\n    if (extParser != null) {\n      try {\n        return extParser.parseSortOrder(orderString);\n      } catch (AnalysisException e) {\n        throw new IllegalArgumentException(\n            String.format(\"Unable to parse sortOrder: %s\", orderString), e);\n      }\n    } else {\n      throw new IllegalStateException(\n          \"Cannot parse order: parser is not an Iceberg ExtendedParser\");\n    }\n  }\n\n  private static <T> T findParser(ParserInterface parser, Class<T> clazz) {\n    ParserInterface current = parser;\n    while (current != null) {\n      if (clazz.isInstance(current)) {\n        return clazz.cast(current);\n      }\n\n      current = getNextDelegateParser(current);\n    }\n","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/ExtendedParser.java#L45-L81","documentation":"ExtendedParser.parseSortOrder delegates order-string parsing (used by REWRITE DATA FILES / sort procedures) to the Iceberg ExtendedParser SQL parser. If parsing raises an AnalysisException, it is rethrown as IllegalArgumentException wrapping the original order string — meaning the SQL sort expression is invalid.","triggerScenarios":"Calling rewrite_data_files (or similar procedures) with an ORDER BY string that is not valid SQL in the current Spark session — misspelled column names, unsupported expressions, wrong quoting.","commonSituations":"Typos in column names; using functions unavailable in the session's SQL dialect; whitespace/quoting mistakes in the order string passed to the stored procedure.","solutions":["Fix the ORDER BY string so it is valid Spark SQL (verify column names and expressions with a plain SELECT ... ORDER BY first)","Check the chained AnalysisException cause for the precise parse error and column reference issue","Ensure the session parser is an Iceberg ExtendedParser (see the related IllegalStateException if not)"],"exampleFix":"// before\nCALL catalog.system.rewrite_data_files(table => 'db.t', strategy => 'sort', sort_order => 'ts DESC, , id')\n// after\nCALL catalog.system.rewrite_data_files(table => 'db.t', strategy => 'sort', sort_order => 'ts DESC, id ASC')","handlingStrategy":"validation","validationCode":"// validate the sort expression with plain SQL before passing it to the procedure\nspark.sql(\"SELECT \" + orderColumns + \" FROM db.t ORDER BY \" + orderString).explain(true);","typeGuard":null,"tryCatchPattern":"try {\n  callRewriteDataFiles(sortOrder);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Unable to parse sortOrder\")) {\n    logger.error(\"Fix the ORDER BY string; cause: \" + e.getCause(), e);\n  } else { throw e; }\n}","preventionTips":["Test the order string in a SELECT ... ORDER BY first","Check the chained AnalysisException for exact column/expression errors","Avoid trailing separators and unsupported functions in sort_order"],"tags":["spark","sql-parser","sort-order","invalid-argument"],"backgroundTag":"invalid-argument-format","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}