{"record":{"id":"cbf0aec67ddf9759","repo":"risingwavelabs/risingwave","slug":"only-append-only-delta-lake-sink-is-supported","errorCode":null,"errorMessage":"only append-only delta lake sink is supported","messagePattern":"only append-only delta lake sink is supported","errorType":"validation","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/deltalake.rs","lineNumber":426,"sourceCode":"            self.param.clone(),\n            inner,\n            commit_checkpoint_interval,\n        )\n        .await?;\n\n        Ok(writer)\n    }\n\n    fn validate_alter_config(config: &BTreeMap<String, String>) -> Result<()> {\n        DeltaLakeConfig::from_btreemap(config.clone())?;\n        Ok(())\n    }\n\n    async fn validate(&self) -> Result<()> {\n        if self.config.r#type != SINK_TYPE_APPEND_ONLY\n            && self.config.r#type != SINK_USER_FORCE_APPEND_ONLY_OPTION\n        {\n            return Err(SinkError::Config(anyhow!(\n                \"only append-only delta lake sink is supported\",\n            )));\n        }\n        let table = self.config.common.create_deltalake_client().await?;\n        let snapshot = table.snapshot()?;\n        let delta_schema = snapshot.schema();\n        let deltalake_fields: HashMap<&String, &DeltaLakeDataType> = delta_schema\n            .fields()\n            .map(|f| (f.name(), f.data_type()))\n            .collect();\n        if deltalake_fields.len() != self.param.schema().fields().len() {\n            return Err(SinkError::DeltaLake(anyhow!(\n                \"Columns mismatch. RisingWave schema has {} fields, DeltaLake schema has {} fields\",\n                self.param.schema().fields().len(),\n                deltalake_fields.len()\n            )));\n        }\n        for field in self.param.schema().fields() {","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/deltalake.rs#L408-L444","documentation":"DeltaLake sink in RisingWave only supports append-only mode. During `validate`, if the sink type is neither `append-only` nor `force_append-only`, validation fails with this Config error before any connection to the table.","triggerScenarios":"Creating a DeltaLake sink without `type = 'append-only'` (or 'force_append-only'), e.g. default/upsert type, or with `type='upsert'` and a primary key defined.","commonSituations":"Users expect upsert/debezium semantics on DeltaLake sinks; omitting the `type` option so a non-append-only default applies; migrating a sink definition from another connector that supports upsert.","solutions":["Add `type = 'append-only'` to the WITH options","Use `type = 'force_append-only'` if the source may emit updates/deletes and you accept append-only behavior","Materialize the data first and sink from an append-only source/stream","Choose a different sink connector that supports upsert semantics"],"exampleFix":"// before\nCREATE SINK s FROM mv WITH ( connector='deltalake', ... )\n// after\nCREATE SINK s FROM mv WITH ( connector='deltalake', type='append-only', ... )","handlingStrategy":"validation","validationCode":"// Ensure append-only before CREATE SINK\n-- verify: SELECT * FROM rw_catalog.rw_sinks WHERE name = 's'; -- check sink type after creation\n// Pre-check in app code: include type='append-only' in generated DDL","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set type='append-only' (or 'force_append-only') for DeltaLake sinks","Do not expect upsert semantics from DeltaLake sinks","Use a materialized view with dedup if you need last-value semantics"],"tags":["deltalake","sink","append-only","validation"],"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"}