risingwavelabs/risingwave · error · SinkError::Config

Turbopuffer namespace_column must be varchar, got {:?}

Error message

Turbopuffer namespace_column must be varchar, got {:?}

What it means

The Turbopuffer sink requires the column designated as `namespace_column` to hold varchar values, because namespaces are string identifiers used in the namespace URL. During sink creation (`try_from`), the sink schema is checked and this error is thrown if the column's data type is anything other than VARCHAR. This is a fail-fast config validation so bad types never reach the writer.

Source

Thrown at src/connector/src/sink/turbopuffer.rs:191

        let namespace = match (&config.namespace, &config.namespace_column) {
            (Some(namespace), None) => {
                validate_namespace(namespace)?;
                TurbopufferNamespace::Static(namespace.clone())
            }
            (None, Some(namespace_column)) => {
                let index = schema
                    .fields()
                    .iter()
                    .position(|field| field.name == *namespace_column)
                    .ok_or_else(|| {
                        SinkError::Config(anyhow!(
                            "Turbopuffer namespace_column '{}' not found in sink schema",
                            namespace_column
                        ))
                    })?;
                if schema[index].data_type != DataType::Varchar {
                    return Err(SinkError::Config(anyhow!(
                        "Turbopuffer namespace_column must be varchar, got {:?}",
                        schema[index].data_type
                    )));
                }
                TurbopufferNamespace::Dynamic { index }
            }
            (Some(_), Some(_)) => {
                return Err(SinkError::Config(anyhow!(
                    "Turbopuffer sink requires only one of namespace or namespace_column"
                )));
            }
            (None, None) => {
                return Err(SinkError::Config(anyhow!(
                    "Turbopuffer sink requires either namespace or namespace_column"
                )));
            }
        };

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Cast the column to VARCHAR upstream (e.g. in the MV feeding the sink) or declare it VARCHAR in the sink schema.
  2. Choose a different column that is already VARCHAR for namespace_column.
  3. Compute a varchar namespace column via a generated expression, e.g. `tenant_id::varchar AS namespace` in the source materialization.
  4. If the namespace is fixed, drop namespace_column and use the literal `namespace` option instead.

Example fix

// before
CREATE SINK s FROM mv WITH (
  connector = 'turbopuffer',
  namespace_column = 'tenant_id'  -- tenant_id is INT
);

// after
CREATE MATERIALIZED VIEW mv2 AS
SELECT tenant_id::varchar AS tenant_namespace, * FROM mv;
CREATE SINK s FROM mv2 WITH (
  connector = 'turbopuffer',
  namespace_column = 'tenant_namespace'
);
Defensive patterns

Strategy: validation

Validate before calling

// SQL: verify the namespace column type before creating the sink
SELECT data_type FROM rw_columns WHERE relation = 'mv_for_sink' AND name = 'ns';
// require: data_type == 'VARCHAR'

Prevention

When it happens

Trigger: Creating a Turbopuffer sink with `with ('namespace_column' = '<col>')` where `<col>` exists in the sink schema but its declared type is INT, BOOLEAN, VECTOR, etc. rather than VARCHAR.

Common situations: Users point namespace_column at a numeric partition or tenant-id column assuming any column works; type changes via schema evolution make a formerly-varchar column numeric; copy-pasting sink definitions from tables with different column types.

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