risingwavelabs/risingwave · error · SinkError::Config

the type of collection.name.field {} must be varchar

Error message

the type of collection.name.field {} must be varchar

What it means

The dynamic collection-name column's value becomes a MongoDB collection name, so it must be a string (VARCHAR). `validate` fails if the column referenced by `collection.name.field` has any other data type. Non-string types could not produce valid collection names without arbitrary casting rules.

Source

Thrown at src/connector/src/sink/mongodb.rs:357

            let fields = self.schema.fields();

            let coll_field_index = fields
                .iter()
                .enumerate()
                .find_map(|(index, field)| {
                    if &field.name == coll_field {
                        Some(index)
                    } else {
                        None
                    }
                })
                .ok_or(SinkError::Config(anyhow!(
                    "collection.name.field {} not found",
                    coll_field
                )))?;

            if fields[coll_field_index].data_type() != risingwave_common::types::DataType::Varchar {
                return Err(SinkError::Config(anyhow!(
                    "the type of collection.name.field {} must be varchar",
                    coll_field
                )));
            }

            if !self.is_append_only && self.pk_indices.contains(&coll_field_index) {
                return Err(SinkError::Config(anyhow!(
                    "collection.name.field {} must not be equal to the primary key field",
                    coll_field
                )));
            }
        }

        Ok(())
    }

    async fn new_log_sinker(&self, writer_param: SinkWriterParam) -> Result<Self::LogSinker> {
        Ok(MongodbSinkWriter::new(

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Cast the column to VARCHAR in the sink's source query (e.g., `SELECT tenant_id::varchar AS tenant, ...`) and point `collection.name.field` at the new string column.
  2. Or change the upstream column type to VARCHAR.
  3. Keep collection names valid MongoDB identifiers (lowercase, no spaces/special chars).

Example fix

-- before
CREATE SINK s FROM (SELECT tenant_id, ... FROM mv) INTO mongodb WITH (
  connector='mongodb', collection='db.c', collection.name.field='tenant_id'
); -- tenant_id is INT
-- after
CREATE SINK s FROM (SELECT tenant_id::varchar AS tenant, ... FROM mv) INTO mongodb WITH (
  connector='mongodb', collection='db.c', collection.name.field='tenant'
);
Defensive patterns

Strategy: validation

Validate before calling

const f = schema.fields.find(f => f.name === options['collection.name.field']);
if (f && f.type !== 'varchar') {
  throw new Error(`collection.name.field '${f.name}' must be VARCHAR, got ${f.type}`);
}

Type guard

function isVarcharField(f) { return f != null && f.type === 'varchar'; }

Prevention

When it happens

Trigger: CREATE SINK into mongodb with `collection.name.field` pointing to an INT/DATE/etc. column.

Common situations: Routing by a numeric tenant ID or a date column without casting it to a string first.

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


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