risingwavelabs/risingwave · error · SinkError::Config

Turbopuffer sink requires either namespace or namespace_colu

Error message

Turbopuffer sink requires either namespace or namespace_column

What it means

The Turbopuffer sink must know which namespace each document is written to, so exactly one of the static `namespace` option or the per-row `namespace_column` option must be provided. In `try_from`, the (None, None) arm rejects sinks that provide neither.

Source

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

                            "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"
                )));
            }
        };

        // Turbopuffer treats `id` as the document ID in write requests; it is not a schema
        // attribute. Dynamic namespace is also metadata for routing, not a document attribute.
        let excluded_indices = match &namespace {
            TurbopufferNamespace::Static(_) => HashSet::from([pk_index]),
            TurbopufferNamespace::Dynamic { index } => HashSet::from([pk_index, *index]),
        };
        let attribute_indices = (0..schema.len())
            .filter(|idx| !excluded_indices.contains(idx))
            .collect_vec();
        for index in &attribute_indices {
            if schema[*index].name == "id" {
                return Err(SinkError::Config(anyhow!(
                    "Turbopuffer attribute column must not be named id"

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Add `namespace = '<name>'` to the WITH options for a fixed namespace.
  2. Add `namespace_column = '<varchar col>'` for per-row namespaces.
  3. Re-check the sink creation statement against the Turbopuffer sink docs.

Example fix

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

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

Strategy: validation

Validate before calling

if (!withClause.namespace && !withClause.namespace_column) {
  throw new Error('turbopuffer sink needs namespace or namespace_column');
}

Prevention

When it happens

Trigger: Creating a Turbopuffer sink with neither `namespace` nor `namespace_column` in the WITH options.

Common situations: Omitting namespace options from copied config; assuming turbopuffer derives a namespace from the table name; partial template rendering that dropped the namespace key.

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/3f4e1b20a0ce078b. Report an issue: GitHub.