{"record":{"id":"2081d7ff3350d65d","repo":"risingwavelabs/risingwave","slug":"internal-error-entered-unreachable-code-2081d7","errorCode":null,"errorMessage":"internal error: entered unreachable code","messagePattern":"internal error: entered unreachable code","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/logical_scan.rs","lineNumber":605,"sourceCode":"            && self\n                .base\n                .ctx()\n                .session_ctx()\n                .config()\n                .enable_index_selection()\n        {\n            let index_selection_rule = IndexSelectionRule::create();\n            if let ApplyResult::Ok(applied) = index_selection_rule.apply(new.clone().into()) {\n                if let Some(scan) = applied.as_logical_scan() {\n                    // covering index\n                    return required_order.enforce_if_not_satisfies(scan.to_batch()?);\n                } else if let Some(join) = applied.as_logical_join() {\n                    // index lookup join\n                    if let Some(lookup_join) = join.index_lookup_join_to_batch_lookup_join()? {\n                        return required_order.enforce_if_not_satisfies(lookup_join);\n                    }\n                } else {\n                    unreachable!();\n                }\n            }\n\n            // Try to make use of index if it satisfies the required order.\n            // Also reach here when a cost-selected non-covering index candidate cannot be\n            // converted to a physical lookup join.\n            if let Some(plan_ref) = new.use_index_scan_if_order_is_satisfied(required_order) {\n                return plan_ref;\n            }\n        }\n        new.to_batch_inner_with_required(required_order)\n    }\n}\n\nimpl ToStream for LogicalScan {\n    fn to_stream(\n        &self,\n        ctx: &mut ToStreamContext,","sourceCodeStart":587,"sourceCodeEnd":623,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/logical_scan.rs#L587-L623","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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."],"exampleFix":"// before\n} else {\n    unreachable!();\n}\n// after\n} else {\n    // Fall back to enforcing order on the applied plan instead of panicking.\n    return required_order.enforce_if_not_satisfies(applied);\n}","handlingStrategy":"try-catch","validationCode":"// No user-side validation possible; capture the failing query and plan for reporting.\nlet plan_text = match rw.explain(\"batch\", sql) {\n    Ok(p) => p,\n    Err(e) => { log::error!(\"optimizer plan unavailable: {e}\"); return; }\n};","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"entered unreachable code\") => {\n        // optimizer bug: rewrite query without ORDER-BY-on-index dependency and report\n    }\n    r => r?,\n}","preventionTips":["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."],"tags":["rust","optimizer","unreachable","index-lookup-join","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}