{"record":{"id":"8a4ad009fb2ad50b","repo":"risingwavelabs/risingwave","slug":"builder-should-have-yielded-a-chunk","errorCode":null,"errorMessage":"builder should have yielded a chunk","messagePattern":"builder should have yielded a chunk","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/row_merge.rs","lineNumber":189,"sourceCode":"        }\n\n        for (i, (_, rhs_row)) in rhs_chunk.rows().enumerate() {\n            for (j, d) in rhs_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) = rhs_mapping.try_map(j) {\n                    merged_rows[i][out_index] = d.to_owned_datum();\n                }\n            }\n        }\n        let mut builder = DataChunkBuilder::new(data_types.to_vec(), cardinality);\n        for row in merged_rows {\n            if let Some(chunk) = builder.append_one_row(&row[..]) {\n                return Ok(Message::Chunk(StreamChunk::from_parts(ops, chunk)));\n            }\n        }\n        bail!(\"builder should have yielded a chunk\")\n    }\n}\n\nimpl Execute for RowMergeExecutor {\n    fn execute(self: Box<Self>) -> BoxedMessageStream {\n        self.execute_inner().boxed()\n    }\n}\n","sourceCodeStart":171,"sourceCodeEnd":198,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/row_merge.rs#L171-L198","documentation":"RowMergeExecutor's build_chunk merges rows from a source and upsert batch, buffering them into a DataChunkBuilder sized to the expected cardinality. After appending all merged rows it asserts the builder has already flushed a chunk during iteration; if no chunk was produced the merge produced fewer rows than expected, so the executor treats this as an internal invariant violation and bails.","triggerScenarios":"The merged row iterator (source rows merged with the upsert-state rows) is empty or yields fewer rows than the cardinality passed to DataChunkBuilder::new, so builder.append_one_row never returns Some(chunk) during the loop.","commonSituations":"Internal bugs in merge logic (mismatched sort keys between source and state tables), upstream executor changes that change cardinality assumptions, or corrupt stream state after failover where the source log contains no matching rows.","solutions":["Check the merge logic in RowMergeExecutor::execute_inner to confirm the merged_rows iterator cannot be empty when build_chunk is called","Verify sort key columns match between the source stream and the upsert state table; mismatched keys yield no merged rows","Upgrade or bisect RisingWave versions — this bail typically indicates an executor bug; file an issue with the actor_id and plan if reproducible","Check for recent recovery/failover events that may have left the state table inconsistent with the source log"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// In executor error handling, treat as non-recoverable internal error and log with actor context\nmatch exec_result {\n    Err(e) if e.to_string().contains(\"builder should have yielded a chunk\") => {\n        tracing::error!(actor = %actor_id, \"row merge invariant violated, forcing recovery\");\n        Err(e) // bubble up to trigger recovery, do not retry locally\n    }\n    other => other,\n}","preventionTips":["Add unit tests covering empty and undersized merged row iterators","Assert cardinality assumptions next to DataChunkBuilder::new construction","Keep sort-key column selection for source and state in one shared helper to avoid drift"],"tags":["internal-invariant","stream-executor","rust"],"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"}