risingwavelabs/risingwave · error · BatchError
no chunk in IngestDmlPayloadRequest
Error message
no chunk in IngestDmlPayloadRequest
What it means
Raised in do_ingest_dml_payload when an IngestDmlPayloadRequest arrives over the batch/DML gRPC service without a `chunk` field. The handler requires exactly one data chunk to decode into a StreamChunk; a request without one is an internal protocol violation and is reported as BatchError::Internal with this message.
Source
Thrown at src/batch/src/rpc/service/task_service.rs:338
let table_version_id = init.table_version_id;
let table_dml_handle = self
.env
.dml_manager_ref()
.table_dml_handle(table_id, table_version_id)
.map_err(|err| Status::internal(format!("{}", err.as_report())))?;
Ok((table_dml_handle, init.request_id, init.row_id_index))
}
async fn do_ingest_dml_payload(
table_dml_handle: TableDmlHandleRef,
dml_manager: DmlManagerRef,
request_id: u32,
row_id_index: Option<u32>,
payload: IngestDmlPayloadRequest,
) -> Result<impl Future<Output = risingwave_dml::error::Result<()>> + Send + 'static, BatchError>
{
let pb_chunk = payload.chunk.ok_or_else(|| {
BatchError::Internal(anyhow::anyhow!("no chunk in IngestDmlPayloadRequest"))
})?;
let mut chunk = StreamChunk::from_protobuf(&pb_chunk)
.context("failed to decode chunk")
.map_err(BatchError::Internal)?;
chunk = inject_optional_row_id_column(chunk, row_id_index.map(|index| index as usize));
let txn_id = dml_manager.gen_txn_id();
let mut write_handle = table_dml_handle
.write_handle(request_id, txn_id)
.map_err(BatchError::Dml)?;
write_handle.begin().map_err(BatchError::Dml)?;
write_handle
.write_chunk(chunk)
.await
.map_err(BatchError::Dml)?;
let persistence_future = write_handle
.end_wait_persistence()
.map_err(BatchError::Dml)?;View on GitHub (pinned to 6469eb736d)
Solutions
- Fix the caller to always populate `chunk` before sending IngestDmlPayloadRequest.
- Skip issuing the ingest RPC entirely when there are no rows to write.
- Check client/SDK version skew against the cluster's protobuf definitions and upgrade.
- If it comes from a driver, capture the request with logging and report/inspect why the chunk was empty.
Example fix
// before
// client sends payload even for empty batch
send(IngestDmlPayloadRequest { request_id, chunk: None });
// after
if !rows.is_empty() {
send(IngestDmlPayloadRequest { request_id, chunk: Some(to_protobuf_chunk(rows)) });
} Defensive patterns
Strategy: validation
Validate before calling
// Client-side guard before sending the RPC
if payload.chunk.is_none() {
return; // skip ingest call entirely for empty batches
} Try / catch
match do_ingest_dml_payload(...).await {
Err(BatchError::Internal(msg)) if msg.contains("no chunk in IngestDmlPayloadRequest") => {
// treat as empty batch: skip or re-send with a valid chunk
}
other => other?,
} Prevention
- Never send IngestDmlPayloadRequest without Some(chunk); skip the RPC for empty writes.
- Keep client SDK and cluster protobuf definitions in version sync.
- Add client-side assertion that serialized DML batches contain at least one row or are dropped.
When it happens
Trigger: A client (or older/newer SDK) calls the ingest DML payload RPC (e.g. from the PostgreSQL wire-protocol DML path) but sends the request with `chunk = None` — e.g. an empty batch, a truncated write, or a client that skips chunk serialization when there are no rows.
Common situations: Writing zero rows via a driver that still issues an ingest call, version skew between frontend and client protocol handling, custom tooling built against the DML gRPC API omitting the chunk field.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Can't find {}
- should get start epoch after update vnode bitmap
- query_epoch not set in distributed lookup join
- unspecified AsOf join inequality type
- Pb decode error: {0}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/821f7c0025b92aa8.
Report an issue: GitHub.