risingwavelabs/risingwave · error
Invalid order key: empty item in `{expr}`
Error message
Invalid order key: empty item in `{expr}` What it means
parse_order_key_exprs splits the order_key option string on commas and parses each item. An empty item means a bare or doubled comma (or a trailing/leading comma) was found, so the parser cannot derive a sort column for that position. It is thrown to surface a malformed order_key specification early, before an Iceberg table is created with a bad sort spec.
Source
Thrown at src/connector/src/sink/iceberg/create_table.rs:487
Transform::from_str(&func)
.with_context(|| format!("invalid transform function {}", func))?,
)
};
partition_columns.push((column.to_owned(), transform));
}
Ok(partition_columns)
}
pub fn parse_order_key_exprs(
expr: String,
) -> std::result::Result<Vec<IcebergOrderKeyField>, anyhow::Error> {
let mut order_keys = Vec::new();
let mut seen_columns = std::collections::HashSet::new();
for raw_item in expr.split(',') {
let item = raw_item.trim();
if item.is_empty() {
bail!("Invalid order key: empty item in `{expr}`");
}
let tokens = item.split_whitespace().collect_vec();
if tokens.is_empty() {
bail!("Invalid order key item `{item}`");
}
if tokens.len() > 4 {
bail!(
"Invalid order key item `{item}`\nHINT: Supported format is `column [asc|desc] [nulls first|last]`"
);
}
let column = tokens[0];
if !ORDER_KEY_COLUMN_RE.is_match(column) {
bail!(
"Invalid order key column `{column}`\nHINT: Only plain column names are supported in order_key"
);
}View on GitHub (pinned to 6469eb736d)
Solutions
- Remove the empty item: no leading, trailing, or doubled commas in order_key
- If a column variable is empty at runtime, fix the variable or drop the item before joining
- Print the raw expr (it is embedded in the message) and delete the offending comma
- If dynamic ordering is optional, pass no order_key rather than an empty string
Example fix
// before WITH ( connector = 'iceberg', order_key = 'id, name,' ) // after WITH ( connector = 'iceberg', order_key = 'id, name' )
Defensive patterns
Strategy: validation
Validate before calling
let expr = "id, name"; // user-supplied order_key
let items: Vec<&str> = expr.split(',').map(|s| s.trim()).collect();
if items.iter().any(|i| i.is_empty()) {
return Err(format!("order_key `{expr}` has an empty item; remove doubled/trailing commas"));
} Type guard
fn has_empty_order_key_item(expr: &str) -> bool {
expr.split(',').any(|item| item.trim().is_empty())
} Prevention
- Never end an order_key list with a comma
- Build order_key by joining a non-empty list: cols.join(",")
- Reject empty strings before setting the option — pass no order_key if you have nothing
- Add a config linter that splits on ',' and asserts no blank items
When it happens
Trigger: Calling validate_order_key_columns (via iceberg sink table creation) with an order_key string containing an empty element after comma splitting, e.g. `a,,b`, `a,`, `,a`, or order_key=`""`/`,`.
Common situations: Hand-written DDL with a trailing comma after the last column; programmatically joined column lists where a list element is empty; copy-pasted options with double commas; templated SQL where a variable evaluates to empty.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid order key item `{item}`
- 'copy-on-write' mode is not supported for append-only iceber
- Invalid order key item `{item}` HINT: Supported format is `c
- Invalid order key column `{column}` HINT: Only plain column
- Duplicate column `{column}` in order_key
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/bac6054ece19134a.
Report an issue: GitHub.