{"record":{"id":"6818cd2f21272a0f","repo":"risingwavelabs/risingwave","slug":"must-be-or-6818cd","errorCode":null,"errorMessage":"`{}` must be {}, or {}","messagePattern":"`(.+?)` must be (.+?), or (.+?)","errorType":"validation","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/file_sink/azblob.rs","lineNumber":115,"sourceCode":"impl UnknownFields for AzblobConfig {\n    fn unknown_fields(&self) -> HashMap<String, String> {\n        self.unknown_fields.clone()\n    }\n}\n\ncrate::impl_sink_unknown_fields!(AzblobConfig);\n\nimpl OpendalSinkBackend for AzblobSink {\n    type Properties = AzblobConfig;\n\n    const SINK_NAME: &'static str = AZBLOB_SINK;\n\n    fn from_btreemap(btree_map: BTreeMap<String, String>) -> Result<Self::Properties> {\n        let config =\n            serde_json::from_value::<AzblobConfig>(serde_json::to_value(btree_map).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    fn new_operator(properties: AzblobConfig) -> Result<Operator> {\n        FileSink::<AzblobSink>::new_azblob_sink(properties)\n    }\n\n    fn get_path(properties: Self::Properties) -> String {\n        properties.common.path\n    }\n\n    fn get_engine_type() -> super::opendal_sink::EngineType {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/file_sink/azblob.rs#L97-L133","documentation":"After deserializing AzblobConfig, the azblob sink validates that the user-supplied r#type option equals 'append-only' or 'upsert'. Any other value (or an empty/misspelled one) is rejected with SinkError::Config naming the option and its two allowed values. This is an explicit enumeration check, not a serde failure.","triggerScenarios":"CREATE SINK ... WITH (connector='azblob', type='<something-else>') where type is not exactly 'append-only' or 'upsert' — e.g. type='append', 'overwrite', 'insert', or wrong casing like 'Append-Only'.","commonSituations":"Copying sink syntax from other systems with different type names; guessing the value instead of reading docs; using uppercase or hyphen-less variants; leaving a placeholder value in the DDL.","solutions":["Set type='append-only' if the source emits no updates/deletes.","Set type='upsert' if the source contains updates/deletes and you want key-based overwrite semantics.","Match the value exactly: lowercase with the hyphen, as printed in the error.","Do not leave the option empty or abbreviated; one of the two literal values is required."],"exampleFix":"// before\nWITH (connector = 'azblob', type = 'append');\n// after\nWITH (connector = 'azblob', type = 'append-only');","handlingStrategy":"validation","validationCode":"match opts.get(\"r#type\").map(String::as_str) {\n    Some(\"append-only\") | Some(\"upsert\") => Ok(()),\n    other => Err(format!(\"azblob sink r#type must be 'append-only' or 'upsert', got {other:?}\")),\n}","typeGuard":null,"tryCatchPattern":"match AzblobSink::from_btreemap(opts) {\n    Ok(cfg) => proceed(cfg),\n    Err(SinkError::Config(e)) => eprintln!(\"invalid sink type: {e:#}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Copy the type value verbatim from the error message or docs: 'append-only' or 'upsert'.","Never hand-type the value; reuse a known-good DDL template.","Remember the value is case-sensitive and hyphenated.","Choose 'upsert' whenever the upstream can retract or update records."],"tags":["sink","config","validation","azblob"],"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"}