risingwavelabs/risingwave · error · SinkError::Config
Turbopuffer document id column must be an integer or varchar
Error message
Turbopuffer document id column must be an integer or varchar, got {:?} What it means
Raised in TryFrom<SinkParam> for the Turbopuffer sink when the single primary-key column's data type is not one of the accepted integer/varchar types. Turbopuffer document IDs must be unsigned 64-bit integers, UUIDs, or strings up to 64 bytes, so a PK of e.g. floating-point or struct type cannot be used as the document id and sink creation fails.
Source
Thrown at src/connector/src/sink/turbopuffer.rs:166
type Error = SinkError;
fn try_from(param: SinkParam) -> std::result::Result<Self, Self::Error> {
let schema = param.schema();
let pk_indices = param.downstream_pk_or_empty();
let [pk_index] = pk_indices.as_slice() else {
return Err(SinkError::Config(anyhow!(
"Turbopuffer sink requires exactly one primary_key column"
)));
};
let pk_index = *pk_index;
match schema[pk_index].data_type() {
DataType::Int16
| DataType::Int32
| DataType::Int64
| DataType::Serial
| DataType::Varchar => {}
data_type => {
return Err(SinkError::Config(anyhow!(
"Turbopuffer document id column must be an integer or varchar, got {:?}",
data_type
)));
}
};
let config = TurbopufferConfig::from_btreemap(param.properties)?;
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(|| {View on GitHub (pinned to 6469eb736d)
Solutions
- Cast the PK column to VARCHAR (or an integer type) in an upstream materialized view
- Change the id column type at the source to an integer or varchar
- Pick a different unique column of supported type as the primary key
Example fix
// before CREATE MATERIALIZED VIEW mv AS SELECT created_at AS id, ... ; -- timestamp id // after CREATE MATERIALIZED VIEW mv AS SELECT created_at::VARCHAR AS id, ... ;
Defensive patterns
Strategy: validation
Validate before calling
const t = pkColumn.type; if (!['int16','int32','int64','serial','varchar'].includes(t)) throw new Error('unsupported id type: ' + t) Type guard
const isSupportedIdType = (dt) => ['Int16','Int32','Int64','Serial','Varchar'].includes(dt);
Try / catch
catch (SinkError::Config(e)) if e.contains('integer or varchar') { cast id column upstream } Prevention
- Cast timestamp/decimal ids to VARCHAR upstream
- Prefer serial/integer surrogate keys for turbopuffer sinks
- Verify PK type during schema review
When it happens
Trigger: CREATE SINK with connector='turbopuffer' where the single PK column has an unsupported data type like Decimal, Timestamp, Float64, or a struct.
Common situations: Using a timestamp or decimal as the natural id; composite key collapsed into a struct/array column.
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
- Turbopuffer sink requires exactly one primary_key column
- Turbopuffer document id column must be an integer or varchar
- Turbopuffer sink does not support column type {}
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
- Join key types are not aligned: LHS: {outer_type:?}, RHS: {i
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/81a14bfdcc5be762.
Report an issue: GitHub.