{"record":{"id":"cdee2a53d876e1ee","repo":"risingwavelabs/risingwave","slug":"rhs-buffer-should-not-be-empty","errorCode":null,"errorMessage":"rhs buffer should not be empty ","messagePattern":"rhs buffer should not be empty ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/row_merge.rs","lineNumber":126,"sourceCode":"                    }\n                }\n            }\n        }\n    }\n\n    #[try_stream(ok = Message, error = StreamExecutorError)]\n    async fn flush_buffers<'a>(\n        data_types: &'a [DataType],\n        lhs_mapping: &'a ColIndexMapping,\n        rhs_mapping: &'a ColIndexMapping,\n        lhs_buffer: &'a mut Vec<StreamChunk>,\n        rhs_buffer: &'a mut Vec<StreamChunk>,\n    ) {\n        if lhs_buffer.is_empty() {\n            bail!(\"lhs buffer should not be empty \");\n        };\n        if rhs_buffer.is_empty() {\n            bail!(\"rhs buffer should not be empty \");\n        };\n\n        for lhs_chunk in lhs_buffer.drain(..) {\n            for rhs_chunk in rhs_buffer.drain(..) {\n                yield Self::build_chunk(\n                    data_types,\n                    lhs_mapping,\n                    rhs_mapping,\n                    lhs_chunk.clone(),\n                    rhs_chunk,\n                )?;\n            }\n        }\n    }\n\n    fn build_chunk(\n        data_types: &[DataType],\n        lhs_mapping: &ColIndexMapping,","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/row_merge.rs#L108-L144","documentation":"Identical invariant to the lhs check in `flush_buffers`: the row-merge executor requires at least one buffered chunk on the right (rhs) side before it can pair chunks. Draining an empty rhs buffer means the right input never staged data for the epoch being flushed.","triggerScenarios":"Internal: `flush_buffers` called when the rhs buffer was never populated for the current epoch — right input barrier arrived without preceding chunks, or epoch bookkeeping desynced between sides.","commonSituations":"Uneven chunk arrival on the two inputs of a row-merge pipeline; upstream right-side actor producing only barriers; version regressions in epoch buffering.","solutions":["Log rhs buffer contents per epoch and file an issue — internal invariant violation, not caused by user SQL","Recreate the streaming job to reset buffer state as a workaround","Check upstream right-side actor health (no chunks at all may indicate a dead/inactive producer)","Upgrade to a RisingWave version with row_merge buffering fixes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match merge_result {\n    Err(e) if e.to_string().contains(\"rhs buffer should not be empty\") => {\n        // Right input never staged chunks for this epoch: recreate the job after checking upstream health\n        verify_right_upstream_actor_health();\n        recreate_streaming_job(job_id);\n    }\n    other => other?,\n}","preventionTips":["Verify the right-side upstream actor is actively producing rows, not only barriers","Monitor per-fragment chunk throughput to catch one-sided stalls early","Keep RisingWave current; epoch buffering bugs are fixed over time","Recreate the job after any cluster failover to reset buffer bookkeeping"],"tags":["rust","streaming","internal-invariant","row-merge"],"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-23T08:17:48.524Z"}