risingwavelabs/risingwave · error
Invalid order key item `{item}`: `NULLS` must be followed by
Error message
Invalid order key item `{item}`: `NULLS` must be followed by `FIRST` or `LAST` What it means
This error is thrown by `parse_order_key_exprs` when an order key item contains the keyword `NULLS` but there is no following token (end of the item string). The parser expects `NULLS` to be immediately followed by `FIRST` or `LAST` to determine null ordering for the Iceberg sort order; a dangling `NULLS` is a syntax error.
Source
Thrown at src/connector/src/sink/iceberg/create_table.rs:525
bail!("Duplicate column `{column}` in order_key");
}
let mut direction = SortDirection::Ascending;
let mut null_order = None;
let mut idx = 1;
while idx < tokens.len() {
match tokens[idx].to_ascii_lowercase().as_str() {
"asc" => {
direction = SortDirection::Ascending;
idx += 1;
}
"desc" => {
direction = SortDirection::Descending;
idx += 1;
}
"nulls" => {
let order = tokens.get(idx + 1).ok_or_else(|| {
anyhow!(
"Invalid order key item `{item}`: `NULLS` must be followed by `FIRST` or `LAST`"
)
})?;
null_order = Some(match order.to_ascii_lowercase().as_str() {
"first" => NullOrder::First,
"last" => NullOrder::Last,
_ => bail!(
"Invalid order key item `{item}`\nHINT: `NULLS` must be followed by `FIRST` or `LAST`"
),
});
idx += 2;
}
token => {
bail!(
"Invalid order key token `{token}` in `{item}`\nHINT: Supported format is `column [asc|desc] [nulls first|last]`"
);
}
}View on GitHub (pinned to 6469eb736d)
Solutions
- Append `FIRST` or `LAST` after `NULLS` in the order key item, e.g. `col asc nulls first`
- Remove the dangling `NULLS` keyword if default null ordering is acceptable
- Verify the full order_key string follows `column [asc|desc] [nulls first|last]`
Example fix
// before order_key = 'ts asc nulls' // after order_key = 'ts asc nulls first'
Defensive patterns
Strategy: validation
Validate before calling
fn is_valid_order_key(item: &str) -> bool {
let toks: Vec<&str> = item.split_whitespace().collect();
match toks.as_slice() {
[_] => true,
[_, d] => matches!(d.to_ascii_lowercase().as_str(), "asc" | "desc"),
[_, d, "nulls", o] if matches!(o.to_ascii_lowercase().as_str(), "first" | "last") => {
matches!(d.to_ascii_lowercase().as_str(), "asc" | "desc")
}
_ => false,
}
}
assert!(order_key.split(',').all(|i| is_valid_order_key(i.trim()))); Try / catch
match parse_order_key_exprs(item) {
Ok(keys) => keys,
Err(e) if e.to_string().contains("NULLS") => {
// fix or drop the NULLS clause, then retry
eprintln!("fix NULLS clause: {e}");
Default::default()
}
Err(e) => return Err(e),
} Prevention
- Always write the full `nulls first`/`nulls last` phrase, never a bare `nulls`
- Validate order_key strings against the documented grammar before submitting sink options
- Prefer omitting the NULLS clause when default null ordering is fine
When it happens
Trigger: Calling the Iceberg sink `order_key` option with an item such as `col asc nulls` (trailing `nulls` with nothing after it) or `col nulls` with no null-order word; typically a typo or a truncated config value.
Common situations: Hand-editing connector options in a CREATE SINK statement or a TOML/CLI config and truncating the value; copy-pasting a partially written sort spec; forgetting `FIRST`/`LAST` after adding `NULLS`.
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}` HINT: `NULLS` must be follow
- Invalid order key token `{token}` in `{item}` HINT: Supporte
- iceberg sink: schema evolution not supported; expect schema
- iceberg sink: partition evolution not supported; expect part
- order_key must not be empty
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/dd939eb7d0ed687c.
Report an issue: GitHub.