risingwavelabs/risingwave · error · SinkError::Config
Primary key not defined for upsert mongodb sink (please defi
Error message
Primary key not defined for upsert mongodb sink (please define in `primary_key` field)
What it means
When a MongoDB sink is created in upsert mode (the stream is not append-only), RisingWave requires an explicit primary key so it can build the MongoDB `_id` field for upserts. `validate` throws this error at sink creation when `pk_indices` is empty, meaning no `primary_key` was defined in the sink's WITH options. Without a PK, upsert semantics cannot be expressed in MongoDB.
Source
Thrown at src/connector/src/sink/mongodb.rs:274
impl TryFrom<SinkParam> for MongodbSink {
type Error = SinkError;
fn try_from(param: SinkParam) -> std::result::Result<Self, Self::Error> {
MongodbSink::new(param)
}
}
impl Sink for MongodbSink {
type LogSinker = AsyncTruncateLogSinkerOf<MongodbSinkWriter>;
const SINK_NAME: &'static str = MONGODB_SINK;
crate::impl_validate_sink_unknown_fields!();
async fn validate(&self) -> Result<()> {
if !self.is_append_only {
if self.pk_indices.is_empty() {
return Err(SinkError::Config(anyhow!(
"Primary key not defined for upsert mongodb sink (please define in `primary_key` field)"
)));
}
// checking if there is a non-pk field's name is `_id`
if self
.schema
.fields
.iter()
.enumerate()
.any(|(i, field)| !self.pk_indices.contains(&i) && field.name == MONGODB_PK_NAME)
{
return Err(SinkError::Config(anyhow!(
"_id field must be the sink's primary key, but a non primary key field name is _id",
)));
}
// assume the sink's pk is (a, b) and then the data written to mongodb will beView on GitHub (pinned to 6469eb736d)
Solutions
- Add `primary_key='your_column'` (or a comma-separated list) to the WITH options of the CREATE SINK statement.
- If the sink should only receive inserts, ensure the upstream stream is append-only (e.g., sink from an append-only source) or use append-only mode so PK is not required.
- If upserting on the full row is intended, specify all columns as the primary key.
Example fix
-- before CREATE SINK s FROM mv INTO mongodb WITH ( connector='mongodb', url='mongodb://localhost:27017', collection='c' ); -- after CREATE SINK s FROM mv INTO mongodb WITH ( connector='mongodb', url='mongodb://localhost:27017', collection='c', primary_key='id' );
Defensive patterns
Strategy: validation
Validate before calling
// Before creating the sink, ensure upsert sinks declare a primary key
const isAppendOnly = /* determined from source */ false;
const hasPk = sinkOptions.primary_key != null && sinkOptions.primary_key.length > 0;
if (!isAppendOnly && !hasPk) {
throw new Error("MongoDB upsert sink requires `primary_key` in WITH options");
} Prevention
- Always set `primary_key` when the upstream can emit updates/deletes
- Only omit primary_key for genuinely append-only streams
- Review sink WITH options in code review
When it happens
Trigger: Creating a `CREATE SINK ... INTO mongodb ...` sink without a `primary_key` option while the source/materialized view is not append-only (i.e., it can emit UPDATE/DELETE events).
Common situations: Developers forgetting to add `primary_key='col'` to the WITH clause when the upstream is a materialized view with updates; assuming a PK on the source table is automatically inherited by the sink.
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
- collection.name.field {} must not be equal to the primary ke
- Primary key not defined for upsert SQL Server sink (please d
- Primary key not defined for upsert clickhouse sink (please d
- Primary key not defined for upsert doris sink (please define
- please set the separator in the with option, when there are
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/975f0fb97ef057bc.
Report an issue: GitHub.