risingwavelabs/risingwave · error · BatchError
Only support insert op in batch source executor
Error message
Only support insert op in batch source executor
What it means
convert_stream_chunk_to_batch_chunk converts chunks read by the batch source executor into batch DataChunks, and only INSERT operations are valid there. A batch query scanning a source expects append-only data; any Delete, UpdateInsert, or UpdateDelete op means the source produced non-append-only stream data and the executor bails out.
Solutions
- Ensure the queried source/table is append-only for batch reads, or filter out mutation records upstream.
- Use a materialized view over the source (which handles updates/deletes) and query the MV instead of the raw source in batch mode.
- If the connector is expected to be append-only, investigate why it emitted Delete/Update ops (e.g. CDC configuration emitting full row changes).
- Check that the stream chunk is compacted before conversion; call chunk.compact() upstream if needed.
Example fix
// before: batch query directly against CDC source emitting updates/deletes SELECT * FROM cdc_source; // after: query a materialized view that handles mutations CREATE MATERIALIZED VIEW mv AS SELECT * FROM cdc_source; SELECT * FROM mv;
Defensive patterns
Strategy: validation
Validate before calling
// Rust: check ops before converting
fn is_append_only(chunk: &StreamChunk) -> bool {
chunk.ops().iter().all(|op| *op == Op::Insert)
} Try / catch
match convert_stream_chunk_to_batch_chunk(chunk) {
Ok(c) => /* consume */,
Err(e) if e.to_string().contains("Only support insert op") => {
// fallback: query a materialized view instead of the raw source
}
} Prevention
- Only batch-query append-only sources; use materialized views for CDC/mutation data.
- Compact stream chunks (chunk.compact()) before conversion.
- Verify connector configuration does not emit deletes/updates on sources read in batch mode.
When it happens
Trigger: Batch source executor reads a StreamChunk whose ops contain anything other than Op::Insert — e.g. the underlying connector/table emits deletes or updates, or the chunk was not visibility-compacted (the preceding assert fails).
Common situations: Pointing a batch query at a source or table that can emit mutation records (CDC with deletes/updates) when the batch path only supports append-only reads; connector or stream-fragment bugs producing non-insert ops; version changes where batch source semantics changed.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Source should not have input executor!
- `Delete` operation is not supported in `append_only` mode
- failed to get row stream from mysql query
- File sink only supports append-only mode at present. Please…
- GenerateSeriesExecutor should not have child!
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/f252d546d9be7e98.
Report an issue: GitHub.
Appendix: source
Thrown at src/batch/executors/src/executor/source.rs:184
for event in stream {
let chunk = match event.map_err(BatchError::connector)? {
SourceReaderEvent::DataChunk(chunk) => chunk,
SourceReaderEvent::SplitProgress(_) => continue,
};
let data_chunk = convert_stream_chunk_to_batch_chunk(chunk)?;
if data_chunk.capacity() > 0 {
yield data_chunk;
}
}
}
}
fn convert_stream_chunk_to_batch_chunk(chunk: StreamChunk) -> Result<DataChunk> {
// chunk read from source must be compact
assert!(chunk.data_chunk().is_vis_compacted());
if chunk.ops().iter().any(|op| *op != Op::Insert) {
bail!("Only support insert op in batch source executor");
}
Ok(chunk.data_chunk().clone())
}
View on GitHub (pinned to 6469eb736d)