xai-org/x-algorithm · error · anyhow::Error
no user_actions
Error message
no user_actions
What it means
extract_single_user_arrow expects an Arrow RecordBatch containing a column named 'user_actions'. When column_by_name returns None (the column is absent from the batch schema), this error is raised. It typically means upstream data production and this consumer disagree on the expected schema.
Source
Thrown at bdsm/rust/abuse-v3-features/src/lib.rs:260
let decompressed = zstd::decode_all(Cursor::new(raw))?;
let cursor = Cursor::new(decompressed);
let reader = FileReader::try_new(cursor, None)?;
let mut batches = Vec::new();
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");
}
View on GitHub (pinned to 24c60942c5)
Solutions
- Inspect batch.schema() field names to confirm what the producer actually sent
- Align the consumer schema with the producer: fix the column name or update this code to the new field name
- Add a schema assertion/validation step before calling extract to fail fast with a clearer message
- Pin producer and consumer to compatible schema versions in deployment
Example fix
// before
let actions_col = batch
.column_by_name("user_actions")
.ok_or_else(|| anyhow::anyhow!("no user_actions"))?;
// after
let actions_col = batch
.column_by_name("user_actions")
.ok_or_else(|| anyhow::anyhow!(
"no user_actions: batch schema has fields {:?}",
batch.schema().fields().iter().map(|f| f.name()).collect::<Vec<_>>()
))?; Defensive patterns
Strategy: validation
Validate before calling
// Validate the batch schema before extraction
let expected = Schema::new(vec![Field::new("user_actions", DataType::List(Arc::new(Field::new("item", ActionType::data_type(), true))), false)]);
anyhow::ensure!(batch.schema().contains(&expected) || batch.column_by_name("user_actions").is_some(), "unexpected batch schema"); Type guard
fn has_user_actions(batch: &RecordBatch) -> bool {
batch.column_by_name("user_actions").is_some()
} Try / catch
// catch and report the actual schema for fast diagnosis
match extract_batch(batches) {
Err(e) if e.to_string().contains("no user_actions") => {
tracing::error!("schema drift: got fields {:?}", batch.schema());
return Err(e);
}
r => r,
} Prevention
- Assert the expected schema at producer and consumer startup
- Version the feature schema and gate deploys on compatibility checks
- Log the full schema on extraction failures to speed up drift diagnosis
When it happens
Trigger: Calling extract_batch / extract_single_user_arrow on a batch whose schema lacks a 'user_actions' field — e.g. an empty concat input, a renamed column, or a producer writing a different feature schema version.
Common situations: Upstream feature pipeline renamed or dropped the user_actions column, schema drift between producer and consumer versions, or an accidentally empty/mis-routed dataset being fed into the extractor.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- not ListArray
- not StructArray
- Field %s does not belong to %s
- Job config specified EntityType.SemanticCore, but non-semant
- Failed to create consumer for thread {}: {:#}
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/4ea5850f80db0d3f.
Report an issue: GitHub.