{"record":{"id":"2319f906d4f033af","repo":"risingwavelabs/risingwave","slug":"right-barrier-received-while-left-stream-end-2319f9","errorCode":null,"errorMessage":"right barrier received while left stream end","messagePattern":"right barrier received while left stream end","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/lookup/sides.rs","lineNumber":145,"sourceCode":"        RightBarrier,\n    }\n\n    'outer: loop {\n        let (side_status, side_barrier) = 'inner: loop {\n            // Prefer right\n            let select_result = match select(right.next(), left.next()).await {\n                future::Either::Left(x) => future::Either::Right(x),\n                future::Either::Right(x) => future::Either::Left(x),\n            };\n            match select_result {\n                future::Either::Left((None, _)) => {\n                    // left stream end, passthrough right chunks\n                    while let Some(msg) = right.next().await {\n                        match msg? {\n                            w @ Message::Watermark(_) => yield Either::Left(w),\n                            c @ Message::Chunk(_) => yield Either::Left(c),\n                            Message::Barrier(_) => {\n                                bail!(\"right barrier received while left stream end\");\n                            }\n                        }\n                    }\n                    break 'outer;\n                }\n                future::Either::Right((None, _)) => {\n                    // right stream end, passthrough left chunks\n                    while let Some(msg) = left.next().await {\n                        match msg? {\n                            w @ Message::Watermark(_) => yield Either::Right(w),\n                            c @ Message::Chunk(_) => yield Either::Right(c),\n                            Message::Barrier(_) => {\n                                bail!(\"left barrier received while right stream end\");\n                            }\n                        }\n                    }\n                    break 'outer;\n                }","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/lookup/sides.rs#L127-L163","documentation":"The Lookup executor's barrier alignment found the left input stream ended, yet a barrier then arrived from the right input. In RisingWave's two-input contract, upstreams end together or not at all; a barrier after the left side ended means the alignment invariant was broken, so the executor aborts the actor rather than producing undefined output.","triggerScenarios":"Raised inside align_barrier's passthrough loop: after observing a None from the left stream, the loop drains remaining right messages and hits a Message::Barrier from the right input.","commonSituations":"Version skew or a corrupt/misaligned plan where one upstream subtree finishes while another keeps sending barriers; actor scheduling or migration bugs causing asymmetric upstream termination; custom executors producing mismatched upstream lifecycles in tests.","solutions":["Check upstream actors' logs to find why the left input ended early (upstream panic, StopManual, backpressure bug).","Verify the plan topology: both Lookup inputs should drain together; re-plan/re-create the MV if the plan came from an older frontend version.","Ensure the cluster is on a consistent version (no rolling upgrade skew between actors).","If reproducible, capture the fragment graph and report; this is an internal invariant failure, not a user-fixable config issue."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Wrap actor/stream construction so alignment errors surface as job failure:\nmatch executor_result {\n    Err(e) if e.to_string().contains(\"barrier received while\") => {\n        log::error!(\"upstream termination protocol violated: {e}\");\n        // fail the actor / restart the stream graph\n    }\n    _ => {}\n}","preventionTips":["Keep all nodes on the same RisingWave version to avoid protocol skew.","Never manually terminate one upstream branch of a two-input executor in tests.","Monitor actor failure logs for asymmetric upstream termination."],"tags":["streaming","barrier","executor","internal-invariant"],"backgroundTag":"invalid-state-transition","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}