risingwavelabs/risingwave · error · SinkError

please ensure the data type of {} is varchar.

Error message

please ensure the data type of {} is varchar.

What it means

When `index_column` is configured, the sink reads that column's value per row to decide the destination index. `validate_config` requires the column's data type to be VARCHAR, because index names must be strings. If the referenced column has any other type (int, timestamp, etc.) the sink creation fails with this error naming the offending column.

Source

Thrown at src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_config.rs:265

    }

    pub fn validate_config(&self, schema: &Schema) -> Result<()> {
        if self.index_column.is_some() && self.index.is_some()
            || self.index_column.is_none() && self.index.is_none()
        {
            return Err(SinkError::Config(anyhow!(
                "please set only one of the 'index_column' or 'index' properties."
            )));
        }

        if let Some(index_column) = &self.index_column {
            let filed = schema
                .fields()
                .iter()
                .find(|f| &f.name == index_column)
                .unwrap();
            if filed.data_type() != DataType::Varchar {
                return Err(SinkError::Config(anyhow!(
                    "please ensure the data type of {} is varchar.",
                    index_column
                )));
            }
        }

        if let Some(routing_column) = &self.routing_column {
            let filed = schema
                .fields()
                .iter()
                .find(|f| &f.name == routing_column)
                .unwrap();
            if filed.data_type() != DataType::Varchar {
                return Err(SinkError::Config(anyhow!(
                    "please ensure the data type of {} is varchar.",
                    routing_column
                )));
            }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Cast or add a varchar column in the source/materialized view, e.g. `CAST(ts AS varchar) AS index_key`, and point index_column at it
  2. Choose a different varchar column for index_column
  3. Change the upstream schema so the column is varchar before creating the sink

Example fix

// before
CREATE MATERIALIZED VIEW mv AS SELECT id, ts FROM src;
WITH (connector='elasticsearch', index_column='ts')  -- ts is TIMESTAMP
// after
CREATE MATERIALIZED VIEW mv AS SELECT id, CAST(ts AS varchar) AS ts_str FROM src;
WITH (connector='elasticsearch', index_column='ts_str')
Defensive patterns

Strategy: validation

Validate before calling

fn check_index_column_type(schema: &Schema, index_column: &str) -> Result<(), String> {
    match schema.fields().iter().find(|f| f.name == index_column) {
        Some(f) if f.data_type() == DataType::Varchar => Ok(()),
        Some(f) => Err(format!("column {} is {:?}, must be varchar", index_column, f.data_type())),
        None => Err(format!("column {} not found", index_column)),
    }
}

Prevention

When it happens

Trigger: CREATE SINK with `index_column = '<col>'` where `<col>` exists in the sink schema but its declared data type is not VARCHAR. The column lookup itself uses `.unwrap()` so the column must exist; this error fires only on type mismatch.

Common situations: Pointing index_column at an integer id or timestamp column assuming automatic casting; schema evolution changed the column type after the sink was defined; copying a config where the column type differs across environments.

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