risingwavelabs/risingwave · error · SinkError

column '{}' type mismatch: deltalake type is {:?}, RisingWav

Error message

column '{}' type mismatch: deltalake type is {:?}, RisingWave type is {:?}

What it means

After locating the column in both schemas, `check_field_type` compares the RisingWave data type to the DeltaLake data type. If they are not compatible (recursively for structs/lists), validation fails with this error reporting both types and the column name.

Source

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

        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() {
            if !deltalake_fields.contains_key(&field.name) {
                return Err(SinkError::DeltaLake(anyhow!(
                    "column {} not found in deltalake table",
                    field.name
                )));
            }
            let deltalake_field_type = deltalake_fields.get(&field.name).ok_or_else(|| {
                SinkError::DeltaLake(anyhow!("cannot find field type for {}", field.name))
            })?;
            if !check_field_type(&field.data_type, deltalake_field_type)? {
                return Err(SinkError::DeltaLake(anyhow!(
                    "column '{}' type mismatch: deltalake type is {:?}, RisingWave type is {:?}",
                    field.name,
                    deltalake_field_type,
                    field.data_type
                )));
            }
        }
        if self.config.common.commit_checkpoint_interval == 0 {
            return Err(SinkError::Config(anyhow!(
                "`commit_checkpoint_interval` must be greater than 0"
            )));
        }
        Ok(())
    }

    fn is_coordinated_sink(&self) -> bool {
        true
    }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Cast the offending column in the sink query to match the Delta table type (e.g. col::VARCHAR)
  2. Recreate the Delta table with types matching the RisingWave schema
  3. Check nested struct/list element types match on both sides
  4. Review the supported type mapping between RisingWave and DeltaLake

Example fix

// before
CREATE SINK s FROM (SELECT id, ts FROM mv) -- ts is TIMESTAMP, table column is STRING
// after
CREATE SINK s FROM (SELECT id, ts::VARCHAR AS ts FROM mv)
Defensive patterns

Strategy: validation

Validate before calling

-- Cast columns to match Delta table types before sinking
-- SELECT id, amount::DECIMAL AS amount, created_at::VARCHAR AS created_at FROM mv

Prevention

When it happens

Trigger: CREATE SINK into an existing DeltaLake table where a same-named column has an incompatible type — e.g. RisingWave INTEGER vs Delta long, VARCHAR vs struct, or a nested struct/list with a differing element type.

Common situations: Sinking into a table created by another system with wider/different types; RisingWave type changed upstream; a nested struct field added on the RisingWave side but absent in the Delta struct type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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