{"record":{"id":"0e378f2b159af56a","repo":"risingwavelabs/risingwave","slug":"turbopuffer-sink-requires-distance-metric-when-sin","errorCode":null,"errorMessage":"Turbopuffer sink requires distance_metric when sink schema contains vector columns","messagePattern":"Turbopuffer sink requires distance_metric when sink schema contains vector columns","errorType":"validation","errorClass":"SinkError::Config","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/turbopuffer.rs","lineNumber":240,"sourceCode":"                    \"Turbopuffer attribute column must not be named id\"\n                )));\n            }\n        }\n        let full_text_search_columns = parse_column_selection(\n            config.full_text_search_columns.as_deref(),\n            &schema,\n            &attribute_indices,\n        )?;\n        let filterable_columns = parse_column_selection(\n            config.filterable_columns.as_deref(),\n            &schema,\n            &attribute_indices,\n        )?;\n        let has_vector = attribute_indices\n            .iter()\n            .any(|idx| matches!(schema[*idx].data_type, DataType::Vector(_)));\n        if has_vector && config.distance_metric.is_none() {\n            return Err(SinkError::Config(anyhow!(\n                \"Turbopuffer sink requires distance_metric when sink schema contains vector columns\"\n            )));\n        }\n        // This validates every document attribute type before the writer is created:\n        // `build_turbopuffer_schema` calls `turbopuffer_type` for each attribute and\n        // returns a config error for unsupported types.\n        let generated_schema = build_turbopuffer_schema(\n            &schema,\n            &attribute_indices,\n            &full_text_search_columns,\n            &filterable_columns,\n        )?;\n\n        Ok(Self {\n            config,\n            schema,\n            pk_index,\n            namespace,","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/turbopuffer.rs#L222-L258","documentation":"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.","triggerScenarios":"Creating a Turbopuffer sink whose schema includes VECTOR columns but whose WITH clause lacks `distance_metric = 'cosine_distance'` (or euclidean/manhattan).","commonSituations":"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.","solutions":["Add `distance_metric = 'cosine_distance'` (or the metric matching your embedding model) to the WITH options.","If the vector column is not meant for Turbopuffer vector search, remove it from the sink schema or exclude it.","Recreate the sink after editing the WITH clause (sink options are fixed at creation)."],"exampleFix":"// before\nWITH (connector='turbopuffer', namespace='docs', access_key='...');\n\n// after\nWITH (connector='turbopuffer', namespace='docs', access_key='...',\n      distance_metric='cosine_distance');","handlingStrategy":"validation","validationCode":"// SQL: if any vector column exists, distance_metric must be set\nSELECT count(*) FROM rw_columns\nWHERE relation = 'mv_for_sink' AND data_type LIKE 'VECTOR%';\n// if count > 0, require withClause.distance_metric","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set distance_metric when sinking embedding/vector columns","Match the metric to the embedding model's recommended distance"],"tags":["sink","turbopuffer","config","vector","missing-option"],"backgroundTag":"missing-required-config-field","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}