quickwit-oss/tantivy · error

null must be handled separately

Error message

null must be handled separately

What it means

CompositeIntermediateKey::Null represents a missing value in composite aggregation after-keys. Null ordering must be handled by a separate missing-value branch (missing_order logic), so when converting an intermediate key to a pagination order, Null reaching column_pagination_order panics with 'null must be handled separately'.

Source

Thrown at src/aggregation/bucket/composite/mod.rs:323

            ColumnType::F64 | ColumnType::I64 | ColumnType::U64 => ColumnPaginationOrder::Numeric,
            ColumnType::IpAddr => ColumnPaginationOrder::IpAddr,
            ColumnType::DateTime => ColumnPaginationOrder::DateTime,
            ColumnType::Bytes => panic!("unsupported"),
        }
    }
}

impl ToTypePaginationOrder for CompositeIntermediateKey {
    fn column_pagination_order(&self) -> ColumnPaginationOrder {
        match self {
            CompositeIntermediateKey::Bool(_) => ColumnPaginationOrder::Bool,
            CompositeIntermediateKey::Str(_) => ColumnPaginationOrder::Str,
            CompositeIntermediateKey::F64(_)
            | CompositeIntermediateKey::I64(_)
            | CompositeIntermediateKey::U64(_) => ColumnPaginationOrder::Numeric,
            CompositeIntermediateKey::IpAddr(_) => ColumnPaginationOrder::IpAddr,
            CompositeIntermediateKey::DateTime(_) => ColumnPaginationOrder::DateTime,
            CompositeIntermediateKey::Null => panic!("null must be handled separately"),
        }
    }
}

impl ToTypePaginationOrder for CompositeKey {
    fn column_pagination_order(&self) -> ColumnPaginationOrder {
        match self {
            CompositeKey::Bool(_) => ColumnPaginationOrder::Bool,
            CompositeKey::Str(_) => ColumnPaginationOrder::Str,
            CompositeKey::F64(_) | CompositeKey::I64(_) | CompositeKey::U64(_) => {
                ColumnPaginationOrder::Numeric
            }
            CompositeKey::Null => panic!("null must be handled separately"),
        }
    }
}

/// After key is a string that encodes the intermediate composite key as "<type>:<value>"

View on GitHub (pinned to b5d8deb80c)

Solutions

  1. Handle Null keys through the missing_order / precompute_missing_after_key path before computing pagination order.
  2. Filter CompositeIntermediateKey::Null out before calling column_pagination_order.
  3. Report a bug if a Null key legitimately reaches pagination ordering in stock aggregation code.

Example fix

// before
let order = key.column_pagination_order(); // panics on Null
// after
match key {
    CompositeIntermediateKey::Null => /* use missing_order path */,
    _ => key.column_pagination_order(),
}
Defensive patterns

Strategy: type-guard

Validate before calling

if matches!(key, CompositeIntermediateKey::Null) {
    return handle_missing_order(missing_order);
}

Type guard

fn is_non_null_key(k: &CompositeIntermediateKey) -> bool {
    !matches!(k, CompositeIntermediateKey::Null)
}

Prevention

When it happens

Trigger: Calling column_pagination_order() on a CompositeIntermediateKey::Null — i.e. null after-key / bucket key values flowed into the pagination-order computation instead of being handled by the missing-order precompute path (precompute_missing_after_key).

Common situations: Composite aggregation over fields with missing values where after-key pagination includes a null key; custom code consuming CompositeIntermediateKey and calling column_pagination_order on it directly without filtering Null; bug in missing-value ordering propagation.

Related errors


AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05). Data as JSON: /api/errors/79c75a61dc9c1ccd. Report an issue: GitHub.