risingwavelabs/risingwave · error
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
This is a Rust `unreachable!()` panic inside `LogicalScan::to_batch_with_order_required`. The optimizer believes it has selected an index candidate that should convert to a physical plan, but the applied node is neither a join convertible to a lookup join nor one of the other expected shapes, so the exhaustive match falls into the final `else` branch. It is an internal optimizer invariant, not a user-facing error.
Source
Thrown at src/frontend/src/optimizer/plan_node/logical_scan.rs:605
&& self
.base
.ctx()
.session_ctx()
.config()
.enable_index_selection()
{
let index_selection_rule = IndexSelectionRule::create();
if let ApplyResult::Ok(applied) = index_selection_rule.apply(new.clone().into()) {
if let Some(scan) = applied.as_logical_scan() {
// covering index
return required_order.enforce_if_not_satisfies(scan.to_batch()?);
} else if let Some(join) = applied.as_logical_join() {
// index lookup join
if let Some(lookup_join) = join.index_lookup_join_to_batch_lookup_join()? {
return required_order.enforce_if_not_satisfies(lookup_join);
}
} else {
unreachable!();
}
}
// Try to make use of index if it satisfies the required order.
// Also reach here when a cost-selected non-covering index candidate cannot be
// converted to a physical lookup join.
if let Some(plan_ref) = new.use_index_scan_if_order_is_satisfied(required_order) {
return plan_ref;
}
}
new.to_batch_inner_with_required(required_order)
}
}
impl ToStream for LogicalScan {
fn to_stream(
&self,
ctx: &mut ToStreamContext,View on GitHub (pinned to 6469eb736d)
Solutions
- Report the query and plan (enable optimizer plan logging/explain) to RisingWave developers with the SQL that triggered it — this is an optimizer bug.
- Work around by rewriting the query: drop the ORDER BY or avoid relying on the index (e.g. use a full scan / different filter) so index-selection takes a covered path.
- Check your RisingWave version and upgrade; index-to-lookup-join conversion fixes land regularly.
- If you develop RisingWave: inspect `applied.as_logical_join()` coverage and add the missing node kind or a fallback enforcement path before the `else` branch.
Example fix
// before
} else {
unreachable!();
}
// after
} else {
// Fall back to enforcing order on the applied plan instead of panicking.
return required_order.enforce_if_not_satisfies(applied);
} Defensive patterns
Strategy: try-catch
Validate before calling
// No user-side validation possible; capture the failing query and plan for reporting.
let plan_text = match rw.explain("batch", sql) {
Ok(p) => p,
Err(e) => { log::error!("optimizer plan unavailable: {e}"); return; }
}; Try / catch
match result {
Err(e) if e.to_string().contains("entered unreachable code") => {
// optimizer bug: rewrite query without ORDER-BY-on-index dependency and report
}
r => r?,
} Prevention
- Avoid depending on index-satisfied ORDER BY in batch queries until the feature is stable.
- Keep RisingWave upgraded; index selection fixes ship frequently.
- Always capture `EXPLAIN` output when a query fails to attach to bug reports.
- Test index-backed queries in CI before enabling new indexes in production.
When it happens
Trigger: Running a batch query whose ORDER BY is intended to be satisfied via an index, when the cost-based index selection produces an `applied` plan node of an unexpected variant (neither LogicalJoin with an index lookup conversion nor the handled alternatives) in `to_batch_with_order_required`.
Common situations: Hit by RisingWave developers or fuzzers exercising index-backed batch queries with required ordering; typically surfaces after changes to index selection rules or new logical node types added to the optimizer without extending this match.
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
- BatchPosixFsReader should not hit this branch. refer to `bat
- shared node should be handled specially in PlanRef::clone_wi
- TableFunction should be converted to ProjectSet
- update should always be converted to batch plan
- Unprocessed shared node.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/2081d7ff3350d65d.
Report an issue: GitHub.