risingwavelabs/risingwave · error · SinkError::Config

` ` must be set to `varchar

Error message

`{STREAM_COLUMN}` must be set to `varchar`

What it means

Mirror of the channel check for streams: when `value type = 'stream'` and `stream column` is set, `validate` looks up that column in the schema and requires it to be `varchar`. Any other type causes this config error.

Solutions

  1. Cast the column to varchar in the source query and point `stream column` at the casted column.
  2. Choose an existing varchar column for `stream column`.
  3. Use the fixed `stream` option instead if the stream name doesn't vary per row.

Example fix

// before
WITH (connector='redis', value type='stream', stream column='region_id')  -- int
// after
CREATE SINK s FROM (SELECT region_id::varchar AS region, * FROM t) WITH (connector='redis', value type='stream', stream column='region');
Defensive patterns

Strategy: validation

Validate before calling

const col = schema.find(c => c.name === opts['stream column']);
if (col && col.type !== 'varchar') throw new Error('stream column must be varchar');

Type guard

const isVarchar = (c) => c.type === 'varchar';

Try / catch

try { await createSink(cfg); } catch (e) { if (String(e).includes('STREAM_COLUMN` must be set to `varchar`')) recastColumn(cfg['stream column']); else throw e; }

Prevention

When it happens

Trigger: Create a sink with `value type='stream'` and `stream column='<col>'` where `<col>` is int, timestamp, struct, or any non-varchar type.

Common situations: Users select a numeric or timestamp column as the per-row stream name; schema drift after adding a stream column option; copying pubsub `channel` configs across sinks whose column types differ.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/connector/src/sink/redis.rs:466

                    tracing::error!("test:for bug");
                    risingwave_common::license::Feature::RedisSinkStream
                        .check_available()
                        .map_err(|e| anyhow::anyhow!(e))?;
                    let stream = self.format_desc.options.get(STREAM);
                    let stream_column = self.format_desc.options.get(STREAM_COLUMN);
                    if (stream.is_none() && stream_column.is_none())
                        || (stream.is_some() && stream_column.is_some())
                    {
                        return Err(SinkError::Config(anyhow!(
                            "Please specific either `{STREAM}` or `{STREAM_COLUMN}`. They are mutually exclusive options."
                        )));
                    }

                    if let Some(stream_column) = stream_column
                        && let Some(stream_column_type) = all_map.get(stream_column)
                        && (stream_column_type != &DataType::Varchar)
                    {
                        return Err(SinkError::Config(anyhow!(
                            "`{STREAM_COLUMN}` must be set to `varchar`"
                        )));
                    }

                    let value_format =
                        self.format_desc.options.get(VALUE_FORMAT).ok_or_else(|| {
                            SinkError::Config(anyhow!("Cannot find `{VALUE_FORMAT}`"))
                        })?;
                    let key_format = self.format_desc.options.get(KEY_FORMAT).ok_or_else(|| {
                        SinkError::Config(anyhow!(
                            "Cannot find '{KEY_FORMAT}', please set it or use JSON"
                        ))
                    })?;
                    TemplateStringEncoder::check_string_format(key_format, &pk_map)?;
                    TemplateStringEncoder::check_string_format(value_format, &all_map)?;
                }
                _ => {
                    return Err(SinkError::Config(anyhow!(

View on GitHub (pinned to 6469eb736d)