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
- Cast the column to VARCHAR upstream (e.g. in the MV feeding the sink) or declare it VARCHAR in the sink schema.
- Choose a different column that is already VARCHAR for namespace_column.
- Compute a varchar namespace column via a generated expression, e.g. `tenant_id::varchar AS namespace` in the source materialization.
- 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
- Keep namespace columns VARCHAR by convention, casting numeric tenant ids at the MV layer
- Check rw_columns for the column type before sink creation
- Prefer a static `namespace` option when per-row namespaces are not needed
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
- topic field `{}` must be of type string but got {:?}
- Turbopuffer sink requires only one of namespace or namespace
- Turbopuffer sink requires either namespace or namespace_colu
- Turbopuffer attribute column must not be named id
- Turbopuffer sink requires distance_metric when sink schema c
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/1e7f1772c253157b.
Report an issue: GitHub.