{"record":{"id":"615b4588218d3ca3","repo":"databendlabs/databend","slug":"internal-error-entered-unreachable-code-615b45","errorCode":null,"errorMessage":"internal error: entered unreachable code","messagePattern":"internal error: entered unreachable code","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/pipeline/transforms/src/processors/transforms/window/transform_window.rs","lineNumber":938,"sourceCode":"            FrameBound::Preceding(_) => {\n                self.frame_started = true;\n            }\n            FrameBound::Following(Some(n)) => {\n                debug_assert!(self.frame_unit.is_rows() || self.order_by.len() == 1);\n\n                if self.is_null_frame {\n                    self.frame_started = true;\n                    self.frame_start = self.peer_group_start;\n                } else if self.frame_unit.is_rows() {\n                    self.advance_frame_start_rows_following(self.rows_start_bound);\n                } else if self.order_by[0].is_nullable {\n                    self.advance_frame_nullable_range::<FrameStart>(n.clone(), false)?;\n                } else {\n                    self.advance_frame_range::<FrameStart>(n.clone(), false)?;\n                }\n            }\n            FrameBound::Following(_) => {\n                unreachable!()\n            }\n        }\n        Ok(())\n    }\n\n    fn advance_frame_end(&mut self) -> Result<()> {\n        debug_assert!(!self.frame_ended);\n\n        match &self.end_bound {\n            FrameBound::CurrentRow => {\n                self.advance_frame_end_current_row();\n            }\n            FrameBound::Preceding(Some(n)) => {\n                debug_assert!(self.frame_unit.is_rows() || self.order_by.len() == 1);\n\n                if self.is_null_frame {\n                    self.advance_frame_end_current_row();\n                } else if self.frame_unit.is_rows() {","sourceCodeStart":920,"sourceCodeEnd":956,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/pipeline/transforms/src/processors/transforms/window/transform_window.rs#L920-L956","documentation":"`unreachable!()` in `TransformWindow::advance_frame_start` (transform_window.rs): the frame-start bound is asserted to never be a `FrameBound::Following` at this point, because a FOLLOWING start would make the frame start 'after' the current row — the state machine processes start bounds only as Preceding/CurrentRow. Hitting it means a window frame with a FOLLOWING start bound reached the start-advancing code path.","triggerScenarios":"Running a window query whose frame definition has a FOLLOWING start, e.g. `ROWS BETWEEN 2 FOLLOWING AND 5 FOLLOWING` or `RANGE BETWEEN UNBOUNDED FOLLOWING AND ...`, so `advance_frame_start` matches `FrameBound::Following(_)` and panics.","commonSituations":"Users writing non-standard frames like `BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING` that the planner passes through to the executor unvalidated; older clients/scripts generating frames programmatically.","solutions":["Rewrite the query to use a valid frame: start bounds must be PRECEDING or CURRENT ROW (e.g. `ROWS BETWEEN UNBOUNDED PRECEDING AND 5 FOLLOWING`).","Validate/reject FOLLOWING start bounds in the planner/binder so the query fails with a clear semantic error instead of a panic.","Upgrade Databend if a newer version adds proper validation or support for such frames.","Reproduce with the exact SQL and file an issue including the window spec."],"exampleFix":"-- before (panics)\nSELECT sum(x) OVER (ORDER BY ts ROWS BETWEEN 2 FOLLOWING AND 5 FOLLOWING) FROM t;\n-- after\nSELECT sum(x) OVER (ORDER BY ts ROWS BETWEEN 2 PRECEDING AND 5 FOLLOWING) FROM t;","handlingStrategy":"validation","validationCode":"// validate the frame before running the window query\n-- start bound must be PRECEDING or CURRENT ROW\nSELECT ... OVER (ORDER BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND 5 FOLLOWING);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never write frames whose start bound is FOLLOWING.","Add binder-level validation for frame bounds.","Keep SQL generators/ORMs from emitting reversed frames.","Test window SQL against a lint that checks frame semantics."],"tags":["rust","panic","window-function","frame-bound","sql"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}