risingwavelabs/risingwave · error · BatchError
ValuesExecutor should have no child!
Error message
ValuesExecutor should have no child!
What it means
ValuesExecutor's builder requires zero child executors. A VALUES clause generates rows from literal expression tuples only and is always a leaf in the batch plan, so receiving an input executor means the plan tree was constructed incorrectly.
Source
Thrown at src/batch/executors/src/executor/values.rs:109
let columns: Vec<_> = array_builders
.into_iter()
.map(|b| b.finish().into())
.collect();
let chunk = DataChunk::new(columns, chunk_size);
yield chunk
}
}
}
}
impl BoxedExecutorBuilder for ValuesExecutor {
async fn new_boxed_executor(
source: &ExecutorBuilder<'_>,
inputs: Vec<BoxedExecutor>,
) -> Result<BoxedExecutor> {
ensure!(inputs.is_empty(), "ValuesExecutor should have no child!");
let value_node = try_match_expand!(
source.plan_node().get_node_body().unwrap(),
NodeBody::Values
)?;
let mut rows: Vec<Vec<BoxedExpression>> = Vec::with_capacity(value_node.get_tuples().len());
for row in value_node.get_tuples() {
let expr_row: Vec<_> = row.get_cells().iter().map(build_from_prost).try_collect()?;
rows.push(expr_row);
}
let fields = value_node
.get_fields()
.iter()
.map(Field::from)
.collect::<Vec<Field>>();
Ok(Box::new(Self {View on GitHub (pinned to 6469eb736d)
Solutions
- Verify the plan tree so the Values node has no children; fix the frontend/batch planner accordingly.
- Ensure VALUES row data is expressed via value_node.tuples expressions rather than child executors.
- Pass an empty inputs vec when constructing ValuesExecutor directly in tests.
- Report an internal bug with the query if the plan seems valid.
Example fix
// before BatchPlanNode::new(NodeBody::Values(values_node), vec![child]) // after BatchPlanNode::new(NodeBody::Values(values_node), vec![])
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: VALUES must be a leaf plan node assert!(inputs.is_empty(), "Values must have no children");
Type guard
fn is_leaf(inputs: &[BoxedExecutor]) -> bool { inputs.is_empty() } Try / catch
if let Err(e) = builder.new_boxed_executor(&src, inputs).await {
if e.to_string().contains("ValuesExecutor should have no child") {
// dump plan and fix planner arity
}
} Prevention
- Construct Values nodes with empty children lists.
- Represent VALUES rows as expression tuples only.
- Add arity assertions in planner tests.
When it happens
Trigger: new_boxed_executor receives a non-empty `inputs` vector because a Values plan node has children attached.
Common situations: Planner bugs attaching a child under a Values node (e.g. when wrapping VALUES in a project/limit and misplacing it in the tree); hand-built plans in tests; internal refactors changing arity rules.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Row sequential scan should not have input executor!
- Source should not have input executor!
- Row sequential scan should not have input executor!
- VectorIndexNearest should have an input executor!
- GenerateSeriesExecutor should not have child!
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/6a7318cb6022d7e2.
Report an issue: GitHub.