{"record":{"id":"903359afa27b9a25","repo":"risingwavelabs/risingwave","slug":"must-be-or-903359","errorCode":null,"errorMessage":"`{}` must be {}, or {}","messagePattern":"`(.+?)` must be (.+?), or (.+?)","errorType":"validation","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/doris.rs","lineNumber":118,"sourceCode":"    #[serde(flatten)]\n    pub unknown_fields: std::collections::HashMap<String, String>,\n}\n\ncrate::impl_sink_unknown_fields!(DorisConfig);\n\nimpl EnforceSecret for DorisConfig {\n    fn enforce_one(prop: &str) -> crate::error::ConnectorResult<()> {\n        DorisCommon::enforce_one(prop)\n    }\n}\n\nimpl DorisConfig {\n    pub fn from_btreemap(properties: BTreeMap<String, String>) -> Result<Self> {\n        let config =\n            serde_json::from_value::<DorisConfig>(serde_json::to_value(properties).unwrap())\n                .map_err(|e| SinkError::Config(anyhow!(e)))?;\n        if config.r#type != SINK_TYPE_APPEND_ONLY && config.r#type != SINK_TYPE_UPSERT {\n            return Err(SinkError::Config(anyhow!(\n                \"`{}` must be {}, or {}\",\n                SINK_TYPE_OPTION,\n                SINK_TYPE_APPEND_ONLY,\n                SINK_TYPE_UPSERT\n            )));\n        }\n        Ok(config)\n    }\n}\n\n#[derive(Debug)]\npub struct DorisSink {\n    pub config: DorisConfig,\n    schema: Schema,\n    pk_indices: Vec<usize>,\n    is_append_only: bool,\n}\n","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/doris.rs#L100-L136","documentation":"The Doris sink config requires the `type` property to be either 'append-only' or 'upsert'. Any other value passed through the WITH options map fails deserialization validation and raises this config error.","triggerScenarios":"Creating a Doris sink whose WITH option `type` (SINK_TYPE_OPTION) is set to anything other than `append-only` or `upsert`, e.g. `type='overwrite'` or a misspelled value.","commonSituations":"Typos in CREATE SINK WITH options; copying a config from another sink connector (Kafka allows other types); case-sensitivity mistakes like `Type='UPSERT'`.","solutions":["Set the sink `type` option to exactly `append-only` or `upsert` (lowercase).","Check for typos or capitalization differences in the WITH clause.","If you need other sink modes, use a connector that supports them; Doris sink supports only these two."],"exampleFix":"// before\nWITH (\n  'connector' = 'doris',\n  'type' = 'overwrite'\n)\n// after\nWITH (\n  'connector' = 'doris',\n  'type' = 'upsert'\n)","handlingStrategy":"validation","validationCode":"const SINK_TYPE: &str = \"upsert\";\nassert!(matches!(SINK_TYPE, \"append-only\" | \"upsert\"));","typeGuard":"fn valid_doris_type(t: &str) -> bool { t == \"append-only\" || t == \"upsert\" }","tryCatchPattern":"match DorisConfig::from_btreemap(props) {\n    Ok(c) => build_sink(c),\n    Err(SinkError::Config(e)) => eprintln!(\"fix sink `type` option: {e}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Keep sink type values lowercase and copy them from documentation.","Lint CREATE SINK statements against the allowed option set.","Store sink configs in version-controlled SQL files and review them."],"tags":["rust","sink","doris","config"],"backgroundTag":"invalid-enum-value","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"}