{"record":{"id":"5d7545f21ccff53f","repo":"apache/druid","slug":"cannot-have-null-or-empty-column-name","errorCode":null,"errorMessage":"Cannot have null or empty column name","messagePattern":"Cannot have null or empty column name","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/frame/key/KeyColumn.java","lineNumber":45,"sourceCode":"\nimport java.util.Objects;\n\n/**\n * Represents a component of a hash or sorting key.\n */\npublic class KeyColumn\n{\n  private final String columnName;\n  private final KeyOrder order;\n\n  @JsonCreator\n  public KeyColumn(\n      @JsonProperty(\"columnName\") String columnName,\n      @JsonProperty(\"order\") KeyOrder order\n  )\n  {\n    if (columnName == null || columnName.isEmpty()) {\n      throw new IAE(\"Cannot have null or empty column name\");\n    }\n\n    this.columnName = columnName;\n    this.order = order;\n  }\n\n  @JsonProperty\n  public String columnName()\n  {\n    return columnName;\n  }\n\n  @JsonProperty\n  public KeyOrder order()\n  {\n    return order;\n  }\n","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/frame/key/KeyColumn.java#L27-L63","documentation":"The KeyColumn constructor in org.apache.druid.frame.key validates that a clustering/sorting key column has a non-null, non-empty name. KeyColumn pairs a column name with a KeyOrder and is used by frame-based sorting and clustering. The library cannot sort or compare keys without a column to reference, so any null or empty name is rejected immediately with IAE.","triggerScenarios":"Constructing `new KeyColumn(null, KeyOrder.ASCENDING)`, `new KeyColumn(\"\", KeyOrder.DESCENDING)`, or building a sort key from a list that contains null/empty column names (e.g. from parsed JSON `{\"columnName\": \"\"}` or a caller-supplied column list where an entry is blank).","commonSituations":"Programmatic assembly of ClusterBy sort keys where column names come from user config, SQL query output, or deserialized JSON; typos that yield empty strings; iterating a schema and appending blank entries; Jackson deserialization of a KeyColumn with a missing/empty columnName property.","solutions":["Pass the exact, non-empty column name that exists in the input frame (case-sensitive).","Before constructing KeyColumn, filter out null/blank strings from the column list.","If names come from user input or config, validate them upfront with a clear error pointing at the offending entry."],"exampleFix":"// before\nList<KeyColumn> key = columns.stream().map(c -> new KeyColumn(c, KeyOrder.ASCENDING)).collect(Collectors.toList());\n// after\nList<KeyColumn> key = columns.stream()\n    .filter(c -> c != null && !c.isEmpty())\n    .map(c -> new KeyColumn(c, KeyOrder.ASCENDING))\n    .collect(Collectors.toList());","handlingStrategy":"validation","validationCode":"if (columnName == null || columnName.isEmpty()) {\n  throw new IllegalArgumentException(\"columnName must be non-null and non-empty\");\n}\nnew KeyColumn(columnName, order);","typeGuard":"boolean isValidKeyColumn(String name) { return name != null && !name.isEmpty(); }","tryCatchPattern":"try {\n  KeyColumn kc = new KeyColumn(name, KeyOrder.ASCENDING);\n} catch (IllegalArgumentException e) {\n  // handle blank column name: skip entry or surface config error\n}","preventionTips":["Never hardcode empty strings as placeholder column names; use null checks upstream.","Validate user/config-supplied column lists at ingestion time.","Filter blank entries before building sort keys."],"tags":["java","argument-validation","sort-key"],"backgroundTag":"empty-required-field","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}