risingwavelabs/risingwave · error · SinkError

only append-only delta lake sink is supported

Error message

only append-only delta lake sink is supported

What it means

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.

Source

Thrown at src/connector/src/sink/deltalake.rs:426

            self.param.clone(),
            inner,
            commit_checkpoint_interval,
        )
        .await?;

        Ok(writer)
    }

    fn validate_alter_config(config: &BTreeMap<String, String>) -> Result<()> {
        DeltaLakeConfig::from_btreemap(config.clone())?;
        Ok(())
    }

    async fn validate(&self) -> Result<()> {
        if self.config.r#type != SINK_TYPE_APPEND_ONLY
            && self.config.r#type != SINK_USER_FORCE_APPEND_ONLY_OPTION
        {
            return Err(SinkError::Config(anyhow!(
                "only append-only delta lake sink is supported",
            )));
        }
        let table = self.config.common.create_deltalake_client().await?;
        let snapshot = table.snapshot()?;
        let delta_schema = snapshot.schema();
        let deltalake_fields: HashMap<&String, &DeltaLakeDataType> = delta_schema
            .fields()
            .map(|f| (f.name(), f.data_type()))
            .collect();
        if deltalake_fields.len() != self.param.schema().fields().len() {
            return Err(SinkError::DeltaLake(anyhow!(
                "Columns mismatch. RisingWave schema has {} fields, DeltaLake schema has {} fields",
                self.param.schema().fields().len(),
                deltalake_fields.len()
            )));
        }
        for field in self.param.schema().fields() {

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Add `type = 'append-only'` to the WITH options
  2. Use `type = 'force_append-only'` if the source may emit updates/deletes and you accept append-only behavior
  3. Materialize the data first and sink from an append-only source/stream
  4. Choose a different sink connector that supports upsert semantics

Example fix

// before
CREATE SINK s FROM mv WITH ( connector='deltalake', ... )
// after
CREATE SINK s FROM mv WITH ( connector='deltalake', type='append-only', ... )
Defensive patterns

Strategy: validation

Validate before calling

// Ensure append-only before CREATE SINK
-- verify: SELECT * FROM rw_catalog.rw_sinks WHERE name = 's'; -- check sink type after creation
// Pre-check in app code: include type='append-only' in generated DDL

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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/cbf0aec67ddf9759. Report an issue: GitHub.