risingwavelabs/risingwave · error · SinkError

`UpdateDelete` operation is not supported in `append_only` m

Error message

`UpdateDelete` operation is not supported in `append_only` mode

What it means

Analogous to the Delete case: in append-only mode the Elasticsearch/OpenSearch formatter cannot handle Op::UpdateDelete rows (the first half of an update). Since append-only streams are assumed never to retract, encountering UpdateDelete violates the contract and conversion fails. The non-append-only branch would instead buffer the row to pair with the following UpdateInsert.

Source

Thrown at src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_formatter.rs:213

                Op::Delete => {
                    if is_append_only {
                        return Err(SinkError::ElasticSearchOpenSearch(anyhow!(
                            "`Delete` operation is not supported in `append_only` mode"
                        )));
                    }
                    let key = self.key_encoder.encode(rows)?.into_string()?;
                    let mem_size_b = std::mem::size_of_val(&key);
                    result_vec.push(BuildBulkPara {
                        index: index.to_owned(),
                        key,
                        value: None,
                        mem_size_b,
                        routing_column,
                    });
                }
                Op::UpdateDelete => {
                    if is_append_only {
                        return Err(SinkError::ElasticSearchOpenSearch(anyhow!(
                            "`UpdateDelete` operation is not supported in `append_only` mode"
                        )));
                    } else {
                        let key = self.key_encoder.encode(rows)?.into_string()?;
                        update_delete_row = Some((key, rows));
                    }
                }
            }
        }
        Ok(result_vec)
    }
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Remove `append_only = true` from the sink so updates are processed in upsert mode.
  2. Recreate the sink without append_only when the input stream contains updates/retracts.
  3. Use an append-only source (e.g., append-only Kafka topic, no UPDATE semantics) with this sink.

Example fix

-- before
CREATE SINK s FROM mv WITH (connector='opensearch', append_only=true);
-- after
CREATE SINK s FROM mv WITH (connector='opensearch', primary_key='id');
Defensive patterns

Strategy: validation

Validate before calling

// verify upstream can emit updates before choosing append_only
// e.g., Debezium changelog sources and updated MVs emit UpdateDelete rows — do not use append_only=true

Try / catch

match err { SinkError::ElasticSearchOpenSearch(msg) if msg.contains("`UpdateDelete` operation is not supported") => recreate_sink_in_upsert_mode(), _ => return Err(err) }

Prevention

When it happens

Trigger: convert_chunk sees Op::UpdateDelete while is_append_only is true — i.e., an append_only sink receives update events from an upsert MV, UPDATE statements, or a changelog source.

Common situations: Sink declared append_only but attached to a materialized view with updates, or a Debezium/ changelog source emitting UPDATE events.

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


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