risingwavelabs/risingwave · error

should not get empty row when decoding stream chunk. start…

Error message

should not get empty row when decoding stream chunk. start seq id: {}, end seq id {}

What it means

Guard in deserialize_stream_chunk: an empty row was decoded where a real row (old/new value of an update) was required. The start/end seq id range and the decoded content are inconsistent; decoding aborts with this error naming the seq id range.

Solutions

  1. The decoder received an empty row within the requested seq-id range, indicating a hole or corruption in the KV log store between the start and end seq ids shown in the message.
  2. Rebuild the affected range from a snapshot or re-execute the log store reads; report if reproducible.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at src/stream/src/common/log_store_impl/kv_log_store/serde.rs:514 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/2abe7944f1bf3a02. Report an issue: GitHub.

Appendix: source

Thrown at src/stream/src/common/log_store_impl/kv_log_store/serde.rs:514

                    ops.push(Op::UpdateDelete);
                    ops.push(Op::UpdateInsert);
                    if ops.len() > size_bound {
                        return Err(anyhow!(
                            "row count {} exceed size bound {}",
                            ops.len(),
                            size_bound
                        ));
                    }
                    assert!(data_chunk_builder.append_one_row(old_value).is_none());
                    assert!(data_chunk_builder.append_one_row(new_value).is_none());
                }
                (_, LogStoreOp::Barrier { .. }) => {
                    return Err(anyhow!("should not get barrier when decoding stream chunk"));
                }
            }
        }
        if ops.is_empty() {
            return Err(anyhow!(
                "should not get empty row when decoding stream chunk. start seq id: {}, end seq id {}",
                start_seq_id,
                end_seq_id
            ));
        }
        read_info.report(metrics);
        Ok(StreamChunk::from_parts(
            ops,
            data_chunk_builder
                .consume_all()
                .expect("should not be empty"),
        ))
    }
}

#[derive(Debug)]
enum StreamState {
    /// The stream has not emitted any row op yet.

View on GitHub (pinned to 6469eb736d)