{"record":{"id":"3460ab101f086b17","repo":"risingwavelabs/risingwave","slug":"lhs-chunk-cardinality-should-be-1-or-2","errorCode":null,"errorMessage":"lhs chunk cardinality should be 1 or 2","messagePattern":"lhs chunk cardinality should be 1 or 2","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/row_merge.rs","lineNumber":150,"sourceCode":"                    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,\n        rhs_mapping: &ColIndexMapping,\n        lhs_chunk: StreamChunk,\n        rhs_chunk: StreamChunk,\n    ) -> Result<Message, StreamExecutorError> {\n        if !(1..=2).contains(&lhs_chunk.cardinality()) {\n            bail!(\"lhs chunk cardinality should be 1 or 2\");\n        }\n        if !(1..=2).contains(&rhs_chunk.cardinality()) {\n            bail!(\"rhs chunk cardinality should be 1 or 2\");\n        }\n        if lhs_chunk.cardinality() != rhs_chunk.cardinality() {\n            bail!(\"lhs and rhs chunk cardinality should be the same\");\n        }\n        let cardinality = lhs_chunk.cardinality();\n        let mut ops = Vec::with_capacity(cardinality);\n        let mut merged_rows = vec![vec![Datum::None; data_types.len()]; cardinality];\n        for (i, (op, lhs_row)) in lhs_chunk.rows().enumerate() {\n            ops.push(op);\n            for (j, d) in lhs_row.iter().enumerate() {\n                // NOTE(kwannoel): Unnecessary columns will not have a mapping,\n                // for instance extra row count column.\n                // those can be skipped here.\n                if let Some(out_index) = lhs_mapping.try_map(j) {\n                    merged_rows[i][out_index] = d.to_owned_datum();","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/row_merge.rs#L132-L168","documentation":"`build_chunk` in the row-merge executor pairs one lhs row with one rhs row, so each chunk must have cardinality 1 or 2 (the executor's designed batching granularity). A lhs chunk with 0 or more than 2 rows violates the executor's batching contract and bails with this error.","triggerScenarios":"Internal: chunks delivered to `build_chunk` contain more than 2 rows (or are empty), meaning upstream buffering failed to split chunks to the expected 1–2 row size before merging.","commonSituations":"Changes in upstream chunking behavior feeding row_merge; bugs where a whole input chunk bypasses the split logic; misuse in tests/custom executor wiring.","solutions":["Capture the actual lhs chunk cardinality (log `lhs_chunk.cardinality()`) and file an issue — this reflects broken internal batching invariants","Recreate the streaming job as a workaround","Check the RisingWave version for known row_merge batching regressions and upgrade","When writing tests against row_merge, ensure test chunks are split to cardinality 1–2 before calling build_chunk"],"exampleFix":"// before (test wiring calling build_chunk directly with a big chunk)\nMessage::Chunk(big_chunk)\n// after\nfor small_chunk in split_chunk(big_chunk, 2) { Message::Chunk(small_chunk) }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match build_result {\n    Err(e) if e.to_string().contains(\"lhs chunk cardinality should be 1 or 2\") => {\n        // Batching invariant broken upstream: file an issue and recreate the job\n        report_issue_with_chunk_trace();\n        recreate_streaming_job(job_id);\n    }\n    other => other?,\n}","preventionTips":["When wiring or testing executors that call build_chunk, split chunks to at most 2 rows first","Add assertions in custom pipelines that chunks entering row_merge are pre-split","Follow upstream chunking regressions in release notes before upgrading","Recreate jobs that previously logged cardinality anomalies"],"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"}