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
- 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.
- Or change the upstream column type to VARCHAR.
- 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
- Cast routing columns to VARCHAR in the sink source query
- Prefer string routing keys (tenant names, slugs) over numeric ids
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
- collection.name.field must be specified when collection.name
- collection.name.field {} not found
- collection.name.field {} must not be equal to the primary ke
- cannot serialize Document to Vec<u8>
- The key encode is BYTES, but the primary key column {} has t
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/30aa75062949600d.
Report an issue: GitHub.