risingwavelabs/risingwave · error · SinkError::Config

Turbopuffer sink requires distance_metric when sink schema c

Error message

Turbopuffer sink requires distance_metric when sink schema contains vector columns

What it means

Turbopuffer vector attributes need a distance metric (e.g. cosine, euclidean) to build the vector index correctly. In `try_from`, if any non-excluded attribute column has type Vector and the `distance_metric` WITH option is unset, sink creation is rejected.

Source

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

                    "Turbopuffer attribute column must not be named id"
                )));
            }
        }
        let full_text_search_columns = parse_column_selection(
            config.full_text_search_columns.as_deref(),
            &schema,
            &attribute_indices,
        )?;
        let filterable_columns = parse_column_selection(
            config.filterable_columns.as_deref(),
            &schema,
            &attribute_indices,
        )?;
        let has_vector = attribute_indices
            .iter()
            .any(|idx| matches!(schema[*idx].data_type, DataType::Vector(_)));
        if has_vector && config.distance_metric.is_none() {
            return Err(SinkError::Config(anyhow!(
                "Turbopuffer sink requires distance_metric when sink schema contains vector columns"
            )));
        }
        // This validates every document attribute type before the writer is created:
        // `build_turbopuffer_schema` calls `turbopuffer_type` for each attribute and
        // returns a config error for unsupported types.
        let generated_schema = build_turbopuffer_schema(
            &schema,
            &attribute_indices,
            &full_text_search_columns,
            &filterable_columns,
        )?;

        Ok(Self {
            config,
            schema,
            pk_index,
            namespace,

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Add `distance_metric = 'cosine_distance'` (or the metric matching your embedding model) to the WITH options.
  2. If the vector column is not meant for Turbopuffer vector search, remove it from the sink schema or exclude it.
  3. Recreate the sink after editing the WITH clause (sink options are fixed at creation).

Example fix

// before
WITH (connector='turbopuffer', namespace='docs', access_key='...');

// after
WITH (connector='turbopuffer', namespace='docs', access_key='...',
      distance_metric='cosine_distance');
Defensive patterns

Strategy: validation

Validate before calling

// SQL: if any vector column exists, distance_metric must be set
SELECT count(*) FROM rw_columns
WHERE relation = 'mv_for_sink' AND data_type LIKE 'VECTOR%';
// if count > 0, require withClause.distance_metric

Prevention

When it happens

Trigger: Creating a Turbopuffer sink whose schema includes VECTOR columns but whose WITH clause lacks `distance_metric = 'cosine_distance'` (or euclidean/manhattan).

Common situations: Adding an embedding column to an existing sink definition and forgetting the metric; copying a text-only sink config to a vector use case; older configs predating the distance_metric requirement.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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