{"record":{"id":"a256baba537c4e54","repo":"apache/iceberg","slug":"unable-to-parse-sortorder-s-a256ba","errorCode":null,"errorMessage":"Unable to parse sortOrder: %s","messagePattern":"Unable to parse sortOrder: (.+?)","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/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.2/spark/src/main/java/org/apache/iceberg/spark/ExtendedParser.java#L45-L81","documentation":"parseSortOrder parses an ORDER BY-like string for Iceberg DDL (e.g. WRITE ORDERED BY). If the wrapped Spark SQL parser (an Iceberg ExtendedParser) throws AnalysisException, it is rethrown as IllegalArgumentException 'Unable to parse sortOrder: <orderString>'.","triggerScenarios":"ALTER TABLE ... WRITE ORDERED BY <expr> or CREATE TABLE ... ORDERED BY with syntactically invalid sort expressions (bad column names, unsupported syntax).","commonSituations":"Misspelled column names in sort order; using Spark SQL syntax unsupported by the Iceberg parser; running a modified Spark whose parser is not the Iceberg ExtendedParser (related IllegalStateException).","solutions":["Fix the order expression: use valid column names and supported directions (ASC/DESC, NULLS FIRST/LAST)","Quote/reserve identifiers if needed and reference only existing columns","Ensure the session SQL parser is the Iceberg ExtendedParser (extensions enabled: spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSqlExtensions)","Check nested-field notation (a.b.c) matches the actual schema"],"exampleFix":"// before\nALTER TABLE t WRITE ORDERED BY unknow_col\n// after\nALTER TABLE t WRITE ORDERED BY known_col DESC NULLS LAST","handlingStrategy":"try-catch","validationCode":"// ensure columns exist before building order string\nList<String> missing = cols.stream().filter(c -> !schema.existsField(c)).collect(Collectors.toList());\nif (!missing.isEmpty()) throw new IllegalArgumentException(\"Unknown sort columns: \" + missing);","typeGuard":null,"tryCatchPattern":"try {\n  sql(String.format(\"ALTER TABLE %s WRITE ORDERED BY %s\", table, order));\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().startsWith(\"Unable to parse sortOrder\")) {\n    log.error(\"Fix order expression syntax/columns: {}\", order, e.getCause());\n  } else throw e;\n}","preventionTips":["Validate column names against the table schema before DDL","Keep to supported syntax: col [ASC|DESC] [NULLS FIRST|LAST]"],"tags":["spark","sql-parsing","sort-order"],"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"}