databendlabs/databend · error
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
In Aggregate::compute_required_prop_child, AggregateMode::Initial must never appear during physical property enforcement: initial aggregation nodes are created/distributed before required-property computation runs, so the arm is marked unreachable. Hitting it means an Initial-mode aggregate reached the property derivation phase, breaking the distributed-aggregation planning invariant.
Solutions
- Check the rule that splits Initial into Partial/Final aggregation ran before this compute_required_prop_child call.
- Log the aggregate's mode and plan context at the panic to confirm which node was unsplit.
- Handle Initial explicitly (set Distribution::Any) instead of panicking if Initial-mode aggregates are legitimate at this stage.
- Verify the physical property framework's visit order — children are derived before parents — is preserved in recent refactorings.
Example fix
// before AggregateMode::Initial => unreachable!(), // after AggregateMode::Initial => required.distribution = Distribution::Any,
Defensive patterns
Strategy: try-catch
Try / catch
// No SQL-level guard; capture and retry on a single node or with simplified aggregation
if err.contains("unreachable code") && query_has_group_by {
exec(set_setting("enable_distributed_aggregation", false), query);
} Prevention
- Ensure aggregation-splitting optimizer settings are not disabled inconsistently across nodes.
- Avoid mixing versions where Initial-mode aggregates can reach property enforcement.
- Test distributed GROUP BY plans after upgrading the cluster.
- Capture EXPLAIN (physical) output when the panic occurs.
When it happens
Trigger: Computing required properties for an Aggregate whose mode is still Initial — e.g. a query plan where partial/final aggregation splitting did not run or ran in the wrong order before property enforcement.
Common situations: Seen during distributed aggregation planning (GROUP BY queries on multi-node setups) after changes to the aggregation-splitting optimizer passes or in single-node plans that mistakenly keep Initial mode.
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
- internal error: entered unreachable code
- plan in InsertInputSource::Stag must be CopyIntoTable
- internal error: entered unreachable code
- internal error: entered unreachable code
- {}
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/7e626400bbc2e4a4.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/sql/src/planner/plans/aggregate.rs:336
if self.group_items.is_empty() {
// Scalar aggregation
required.distribution = Distribution::Any;
} else {
required.distribution = self.get_distribution(ctx)?;
}
}
AggregateMode::Final => {
if self.group_items.is_empty() {
// Scalar aggregation
required.distribution = Distribution::Serial;
} else {
// The distribution should have been derived by partial aggregation
required.distribution = Distribution::Any;
}
}
AggregateMode::Initial => unreachable!(),
}
Ok(required)
}
fn derive_relational_prop(&self, rel_expr: &RelExpr) -> Result<Arc<RelationalProperty>> {
let input_prop = rel_expr.derive_relational_prop_child(0)?;
// Derive output columns
let mut output_columns = ColumnSet::new();
for group_item in self.group_items.iter() {
output_columns.insert(group_item.index);
}
for agg in self.aggregate_functions.iter() {
output_columns.insert(agg.index);
}
// Derive outer columns
let outer_columns = input_propView on GitHub (pinned to 288d84d76e)