databendlabs/databend · error
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
This `unreachable!()` in `VisitorCast::from_visitor` fires when a `downcast_mut::<T>()` on a boxed `PhysicalPlanVisitor` returns None — i.e., the visitor's concrete type does not match the type the cast target expects. The visitor system's invariant is that callers only downcast after a matching type check; a mismatched or unordered check/cast sequence breaks it.
Solutions
- Find the call site performing the unchecked downcast and add/repair the corresponding type check (check_physical_plan / as_any downcast check) before casting
- Ensure every new PhysicalPlan variant has a matching visitor arm so dispatch never routes the wrong visitor type here
- Run the physical-plan visitor tests after adding plan node types to catch dispatch mismatches
- If reproducible on a stock plan, file a Databend bug with the query and plan tree
Example fix
// before
let casted: &mut MyVisitor = from_visitor(boxed); // may unreachable!()
// after
if T::check_physical_plan(plan) {
let casted: &mut MyVisitor = from_visitor(boxed);
} else {
return Err(ErrorCode::Internal("unexpected visitor type"));
} Defensive patterns
Strategy: validation
Validate before calling
// Always verify the concrete visitor type before casting
if !T::check_physical_plan(plan) {
return Err(ErrorCode::Internal("visitor type mismatch"));
} Type guard
fn visitor_is<T: PhysicalPlanVisitor + 'static>(x: &Box<dyn PhysicalPlanVisitor>) -> bool {
x.as_any().is::<T>()
} Try / catch
// Wrap traversal dispatch and fall back to the generic visitor on mismatch
std::panic::catch_unwind(AssertUnwindSafe(|| T::from_visitor(boxed).visit(plan)))
.unwrap_or_else(|_| generic_visit(plan)) Prevention
- Pair every downcast with a preceding as_any().is::<T>() check
- Keep visitor trait implementations and PhysicalPlan variants in sync; add compile-time checks where possible
- Write a test that visits every plan node type through the visitor dispatch
- Avoid hand-rolled casts on dyn visitor objects; use a shared checked helper
When it happens
Trigger: Calling a typed visitor method on a `&mut Box<dyn PhysicalPlanVisitor>` without a preceding `check_physical_plan`/type check, or dispatching to the wrong visitor implementation so the downcast fails.
Common situations: Extending PhysicalPlan with a new node type or visitor and forgetting to keep the visitor dispatch and cast in sync; code refactors that reorder type checks and casts; hand-written visitor traversal code.
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
- internal error: entered unreachable code
- internal error: entered unreachable code
- internal error: entered unreachable code
- unexpected value type for grouping function
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/ca2af03505999703.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/physical_plans/physical_plan.rs:239
)))
}
}
pub trait PhysicalPlanVisitor: Send + Sync + 'static {
fn as_any(&mut self) -> &mut dyn Any;
fn visit(&mut self, plan: &PhysicalPlan) -> Result<()>;
}
pub trait VisitorCast {
fn from_visitor(x: &mut Box<dyn PhysicalPlanVisitor>) -> &mut Self;
}
impl<T: PhysicalPlanVisitor> VisitorCast for T {
fn from_visitor(x: &mut Box<dyn PhysicalPlanVisitor>) -> &mut T {
match x.as_any().downcast_mut::<T>() {
Some(x) => x,
None => unreachable!(),
}
}
}
pub trait PhysicalPlanCast {
fn check_physical_plan(plan: &PhysicalPlan) -> bool;
fn from_physical_plan(plan: &PhysicalPlan) -> Option<&Self>;
fn from_mut_physical_plan(plan: &mut PhysicalPlan) -> Option<&mut Self>;
}
impl<T: IPhysicalPlan> PhysicalPlanCast for T {
fn check_physical_plan(plan: &PhysicalPlan) -> bool {
plan.as_any().downcast_ref::<T>().is_some()
}
fn from_physical_plan(plan: &PhysicalPlan) -> Option<&T> {View on GitHub (pinned to 288d84d76e)