{"record":{"id":"1a08cdb2fc1b8749","repo":"risingwavelabs/risingwave","slug":"please-set-the-separator-in-the-with-option-when","errorCode":null,"errorMessage":"please set the separator in the with option, when there are multiple primary key values","messagePattern":"please set the separator in the with option, when there are multiple primary key values","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_formatter.rs","lineNumber":79,"sourceCode":"                .name;\n            format!(\"{{{}}}\", name)\n        } else if pk_indices.len() == 1 {\n            let index = *pk_indices.get(0).unwrap();\n            let name = &schema\n                .fields()\n                .get(index)\n                .ok_or_else(|| {\n                    SinkError::ElasticSearchOpenSearch(anyhow!(\n                        \"no value find in sink schema, index is {:?}\",\n                        index\n                    ))\n                })?\n                .name;\n            format!(\"{{{}}}\", name)\n        } else {\n            let delimiter = delimiter\n                .as_ref()\n                .ok_or_else(|| anyhow!(\"please set the separator in the with option, when there are multiple primary key values\"))?\n                .clone();\n            let mut names = Vec::with_capacity(pk_indices.len());\n            for index in &pk_indices {\n                names.push(format!(\n                    \"{{{}}}\",\n                    schema\n                        .fields()\n                        .get(*index)\n                        .ok_or_else(|| {\n                            SinkError::ElasticSearchOpenSearch(anyhow!(\n                                \"no value find in sink schema, index is {:?}\",\n                                index\n                            ))\n                        })?\n                        .name\n                ));\n            }\n            names.join(&delimiter)","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_formatter.rs#L61-L97","documentation":"When the sink has multiple primary key columns, the formatter joins their values into a document key using a delimiter. If no `separator` (delimiter) was provided in the WITH options, construction fails with this message, because a multi-column key cannot be serialized unambiguously without one.","triggerScenarios":"Creating an Elasticsearch/OpenSearch sink with 2+ primary key columns and no `separator` option in the WITH clause; checked in the formatter's `new` when `delimiter` is None in the multi-pk branch.","commonSituations":"Sinks with composite primary keys where the author added `primary_key = 'a, b'` but forgot `separator = ','`; copying single-pk sink examples to a composite-key scenario.","solutions":["Add `separator = '<delim>'` to the WITH clause (e.g. separator = '_')","Ensure the delimiter does not appear in the pk column values, to avoid key collisions","Alternatively reduce to a single primary key column to avoid needing a separator","Recreate the sink with the corrected WITH options"],"exampleFix":"// before\nCREATE SINK s FROM mv WITH (connector='elasticsearch', primary_key='user_id, item_id');\n// after\nCREATE SINK s FROM mv WITH (connector='elasticsearch', primary_key='user_id, item_id', separator='_');","handlingStrategy":"validation","validationCode":"fn check_separator_for_composite_pk(with_opts: &Options, pk_len: usize) -> Result<(), String> {\n    if pk_len > 1 && with_opts.get(\"separator\").is_none() {\n        return Err(\"multi-column primary key requires 'separator' in WITH options\".into());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set separator when using a composite primary key","Pick a delimiter that never occurs in pk values","Prefer single-column surrogate keys to avoid delimiter issues"],"tags":["rust","sink","formatter","primary-key","config"],"backgroundTag":"missing-required-option","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"}