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
- 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
- Choose a different varchar column for index_column
- 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
- Add explicit CAST(... AS varchar) columns for dynamic index keys
- Check column types with DESC before wiring index_column
- Keep index-key columns as varchar in upstream views by convention
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
- please set only one of the 'index_column' or 'index' propert
- Cannot find {}
- `{}` must be {}, or {}
- Primary key not defined for upsert doris sink (please define
- Can't get fe host from url
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/8c5e35eb8e7742cc.
Report an issue: GitHub.