{"record":{"id":"8efa547362b44ebd","repo":"risingwavelabs/risingwave","slug":"unreachable-8efa54","errorCode":null,"errorMessage":"unreachable","messagePattern":"unreachable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/src/optimizer/plan_node/logical_kafka_scan.rs","lineNumber":308,"sourceCode":"                },\n            )\n        }\n    }\n}\n\nimpl ToBatch for LogicalKafkaScan {\n    fn to_batch(&self) -> Result<crate::optimizer::plan_node::BatchPlanRef> {\n        let plan = BatchKafkaScan::new(self.core.clone(), self.kafka_timestamp_range).into();\n        Ok(plan)\n    }\n}\n\nimpl ToStream for LogicalKafkaScan {\n    fn to_stream(\n        &self,\n        _ctx: &mut ToStreamContext,\n    ) -> Result<crate::optimizer::plan_node::StreamPlanRef> {\n        unreachable!()\n    }\n\n    fn logical_rewrite_for_stream(\n        &self,\n        _ctx: &mut RewriteStreamContext,\n    ) -> Result<(PlanRef, ColIndexMapping)> {\n        unreachable!()\n    }\n}\n","sourceCodeStart":290,"sourceCodeEnd":318,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/frontend/src/optimizer/plan_node/logical_kafka_scan.rs#L290-L318","documentation":"`LogicalKafkaScan` implements `ToStream::to_stream` with a hard `unreachable!()`. The RisingWave stream optimizer is expected to rewrite Kafka scans into a `StreamSource`/source-backed plan (via DML/source conversion) before the to-stream phase reaches this node, so the conversion method itself is never supposed to be called. Hitting this panic means the frontend's pre-stream rewriting pipeline missed a case and let a `LogicalKafkaScan` survive into direct stream conversion.","triggerScenarios":"Calling `to_stream` on a plan tree that still contains a `LogicalKafkaScan` node, i.e. the optimization passes that should have replaced the Kafka scan with a source-based logical plan did not run or did not match this node.","commonSituations":"Internal frontend bugs: a new query shape introduces a Kafka scan path not covered by the rewriting pass in `LogicalOptimizer`; custom optimizer code or tests that construct `LogicalKafkaScan` directly and then invoke to-stream conversion; version changes where the rewrite rule was moved or renamed.","solutions":["Check why the Kafka-scan rewrite (e.g. DML-to-source conversion in `LogicalOptimizer`) did not replace this node before to-stream; add/fix the rewrite rule so `LogicalKafkaScan` never reaches `to_stream`.","If you construct `LogicalKafkaScan` in code or tests, run it through the standard logical optimization pipeline instead of calling `to_stream` directly.","Reproduce with the offending SQL and file a RisingWave bug with the query plan (`EXPLAIN`) before the panic.","As a local workaround, disable the feature/query shape that produces the Kafka scan until the rewrite is fixed."],"exampleFix":"// before: node survives to to_stream and panics\nlet plan = logical_plan.to_stream(ctx)?; // panics: unreachable in LogicalKafkaScan\n// after: ensure the rewrite pass ran first\nlet plan = LogicalOptimizer::gen_optimized_logical_plan_for_stream(logical_plan)?; // rewrites KafkaScan into source\nlet plan = plan.to_stream(ctx)?;","handlingStrategy":"try-catch","validationCode":"// ensure queries reach to_stream only through the full optimizer\nassert!(!plan_contains::<LogicalKafkaScan>(&plan), \"KafkaScan must be rewritten to source before to_stream\");","typeGuard":"fn is_kafka_scan(node: &PlanNode) -> bool { matches!(node, PlanNode::LogicalKafkaScan(_)) }","tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"unreachable\") => log::error!(\"KafkaScan survived to to_stream; check rewrite pass: {e}\"),\n    other => other?,\n}","preventionTips":["Always plan Kafka queries through the standard optimizer entry points, never call `to_stream` on hand-built plans.","After refactoring optimizer passes, add an assertion that no `LogicalKafkaScan` remains before stream conversion.","Report panics with the offending SQL and plan as RisingWave frontend bugs."],"tags":["rust","stream-optimizer","kafka-scan","panic"],"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-14T11:17:12.474Z"}