xai-org/x-algorithm · error · anyhow::Error
not ListArray
Error message
not ListArray
What it means
After locating the 'user_actions' column, the code downcasts it to arrow::array::ListArray. If the column is any other Arrow type (e.g. LargeListArray, StructArray, or a plain non-nested type), the downcast returns None and this error fires. The producer must emit user_actions as a List array.
Source
Thrown at bdsm/rust/abuse-v3-features/src/lib.rs:264
for b in reader {
batches.push(b?);
}
if batches.is_empty() {
anyhow::bail!("empty");
}
let batch = if batches.len() == 1 {
batches.into_iter().next().unwrap()
} else {
arrow::compute::concat_batches(&batches[0].schema(), &batches)?
};
let actions_col = batch
.column_by_name("user_actions")
.ok_or_else(|| anyhow::anyhow!("no user_actions"))?;
let list = actions_col
.as_any()
.downcast_ref::<ListArray>()
.ok_or_else(|| anyhow::anyhow!("not ListArray"))?;
if list.is_empty() || list.is_null(0) {
anyhow::bail!("empty list");
}
let vals = list.value(0);
let sa = vals
.as_any()
.downcast_ref::<StructArray>()
.ok_or_else(|| anyhow::anyhow!("not StructArray"))?;
let total = sa.len();
if total == 0 {
anyhow::bail!("zero actions");
}
let start = if total > seq_len { total - seq_len } else { 0 };
let take = total.min(seq_len);
let sl = sa.slice(start, take);
let sl = sl.as_any().downcast_ref::<StructArray>().unwrap();View on GitHub (pinned to 24c60942c5)
Solutions
- Print the column's DataType (actions_col.data_type()) to see the actual type
- If it is LargeListArray, either change the producer to emit ListArray or downcast to LargeListArray here
- Regenerate/align the Arrow schema between producer and consumer (field type must be List(...))
- Add an upfront schema check comparing the expected exact DataType before extraction
Example fix
// before
let list = actions_col
.as_any()
.downcast_ref::<ListArray>()
.ok_or_else(|| anyhow::anyhow!("not ListArray"))?;
// after
let list = actions_col
.as_any()
.downcast_ref::<ListArray>()
.ok_or_else(|| anyhow::anyhow!(
"not ListArray: user_actions is {:?}",
actions_col.data_type()
))?; Defensive patterns
Strategy: type-guard
Validate before calling
// Check the column type before downcasting
let dt = batch.column_by_name("user_actions").map(|c| c.data_type().clone());
anyhow::ensure!(matches!(dt, Some(DataType::List(_))), "user_actions must be List, got {dt:?}"); Type guard
fn is_list_array(col: &ArrayRef) -> bool {
matches!(col.data_type(), DataType::List(_))
}
// or handle LargeList too:
fn as_list(col: &ArrayRef) -> Option<&ListArray> {
col.as_any().downcast_ref::<ListArray>()
} Try / catch
// branch on the actual type instead of failing on downcast
let list = match actions_col.data_type() {
DataType::List(_) => actions_col.as_any().downcast_ref::<ListArray>().unwrap(),
DataType::LargeList(_) => /* convert or handle LargeListArray */,
other => anyhow::bail!("unsupported user_actions type: {other:?}"),
}; Prevention
- Pin producer/consumer to the same arrow crate version
- Centralize the expected Arrow schema in one shared constant/module
- In tests, build batches via the shared schema helper rather than hand-rolled types
When it happens
Trigger: Calling extract_batch where the user_actions column is typed as LargeList, Struct, or any non-List Arrow type — commonly after a producer migration to LargeListArray for >2B row support or a hand-built test batch using the wrong type.
Common situations: Arrow version upgrades where readers/writers default to LargeList, alternate producers writing struct-of-list instead of list-of-struct, or test fixtures constructing batches with mismatched types.
Related errors
- not StructArray
- no user_actions
- function passed to Foldl() returns %s but seed value is a %s
- Foldl1 is expected to return %s but passed function returns
- Sort is expected to return %s but passed function returns %s
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/6a306f05a742af10.
Report an issue: GitHub.