{"record":{"id":"ef9731d514f371ac","repo":"risingwavelabs/risingwave","slug":"delete-operation-is-not-supported-in-append-onl","errorCode":null,"errorMessage":"`Delete` operation is not supported in `append_only` mode","messagePattern":"`Delete` operation is not supported in `append_only` mode","errorType":"validation","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_formatter.rs","lineNumber":197,"sourceCode":"                                } else {\n                                    modified_col_indices.push(index);\n                                }\n                            });\n                    }\n                    let value = self\n                        .value_encoder\n                        .encode_cols(rows, modified_col_indices.into_iter())?;\n                    result_vec.push(BuildBulkPara {\n                        index: index.to_owned(),\n                        key,\n                        value: Some(value),\n                        mem_size_b: rows.value_estimate_size(),\n                        routing_column,\n                    });\n                }\n                Op::Delete => {\n                    if is_append_only {\n                        return Err(SinkError::ElasticSearchOpenSearch(anyhow!(\n                            \"`Delete` operation is not supported in `append_only` mode\"\n                        )));\n                    }\n                    let key = self.key_encoder.encode(rows)?.into_string()?;\n                    let mem_size_b = std::mem::size_of_val(&key);\n                    result_vec.push(BuildBulkPara {\n                        index: index.to_owned(),\n                        key,\n                        value: None,\n                        mem_size_b,\n                        routing_column,\n                    });\n                }\n                Op::UpdateDelete => {\n                    if is_append_only {\n                        return Err(SinkError::ElasticSearchOpenSearch(anyhow!(\n                            \"`UpdateDelete` operation is not supported in `append_only` mode\"\n                        )));","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_formatter.rs#L179-L215","documentation":"The Elasticsearch/OpenSearch sink formatter is operating in append-only mode (is_append_only), which only supports INSERT operations. When an Op::Delete row arrives in a chunk, the formatter rejects it because append-only mode cannot express document deletions. The chunk conversion returns an error instead of producing a bulk request.","triggerScenarios":"convert_chunk encounters a row with Op::Delete while the sink was created in append-only mode (e.g., sink created with `append_only=true` against a stream that emits deletes, such as an upsert MV or BACKFILL/UPDATE operations).","commonSituations":"Users sink a materialized view that undergoes updates/deletes into an ES sink declared append_only; or schema changes/upstream retracts generate Delete rows unexpectedly.","solutions":["Remove `append_only = true` from the sink options so the sink runs in upsert/debezium mode and can encode deletes.","Only sink append-only streams (e.g., a fact stream that never retracts) when keeping append_only mode.","Pre-filter retracting events upstream if deletes are not meaningful for the target index."],"exampleFix":"// before\nCREATE SINK s FROM mv WITH (connector='elasticsearch', append_only=true);\n// after\nCREATE SINK s FROM mv WITH (connector='elasticsearch', primary_key='id');","handlingStrategy":"validation","validationCode":"-- confirm the stream is truly append-only before using append_only=true\nSHOW MATERIALIZED VIEWS; -- check the source relation never retracts (no UPDATE/DELETE)","typeGuard":null,"tryCatchPattern":"match err { SinkError::ElasticSearchOpenSearch(msg) if msg.contains(\"`Delete` operation is not supported\") => recreate_sink_without_append_only(), _ => return Err(err) }","preventionTips":["Only set append_only=true for streams known to never emit retracts.","Avoid sinking upsert materialized views into append_only sinks.","Provide a primary_key so the sink defaults to upsert mode."],"tags":["elasticsearch","sink","append-only","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}