{"record":{"id":"7762ecec60a411bd","repo":"risingwavelabs/risingwave","slug":"invalid-write-mode-must-be-one-of","errorCode":null,"errorMessage":"invalid write_mode: {}, must be one of: {}, {}","messagePattern":"invalid write_mode: (.+?), must be one of: (.+?), (.+?)","errorType":"validation","errorClass":"SinkError::Config","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/iceberg/config.rs","lineNumber":75,"sourceCode":"}\n\nimpl IcebergWriteMode {\n    pub fn as_str(self) -> &'static str {\n        match self {\n            IcebergWriteMode::MergeOnRead => ICEBERG_WRITE_MODE_MERGE_ON_READ,\n            IcebergWriteMode::CopyOnWrite => ICEBERG_WRITE_MODE_COPY_ON_WRITE,\n        }\n    }\n}\n\nimpl std::str::FromStr for IcebergWriteMode {\n    type Err = SinkError;\n\n    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {\n        match s {\n            ICEBERG_WRITE_MODE_MERGE_ON_READ => Ok(IcebergWriteMode::MergeOnRead),\n            ICEBERG_WRITE_MODE_COPY_ON_WRITE => Ok(IcebergWriteMode::CopyOnWrite),\n            _ => Err(SinkError::Config(anyhow!(format!(\n                \"invalid write_mode: {}, must be one of: {}, {}\",\n                s, ICEBERG_WRITE_MODE_MERGE_ON_READ, ICEBERG_WRITE_MODE_COPY_ON_WRITE\n            )))),\n        }\n    }\n}\n\nimpl TryFrom<&str> for IcebergWriteMode {\n    type Error = <Self as std::str::FromStr>::Err;\n\n    fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {\n        value.parse()\n    }\n}\n\nimpl TryFrom<String> for IcebergWriteMode {\n    type Error = <Self as std::str::FromStr>::Err;\n","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/iceberg/config.rs#L57-L93","documentation":"This is the FromStr parser for the `IcebergWriteMode` sink option. It only accepts the exact strings defined by ICEBERG_WRITE_MODE_MERGE_ON_READ (\"merge-on-read\") and ICEBERG_WRITE_MODE_COPY_ON_WRITE (\"copy-on-write\"); any other value for the `write_mode` connector property fails sink validation with this config error. It is thrown at sink creation time before any data is written.","triggerScenarios":"A CREATE SINK ... WITH (connector='iceberg', write_mode='...') statement supplies a write_mode string that is not exactly 'merge-on-read' or 'copy-on-write' (typo, wrong case, extra whitespace, or a value from another system such as 'mor' or 'upsert').","commonSituations":"Copy-pasting options from a different engine's iceberg connector docs; misspelling like 'merge_on_read' with underscores; using quotes/case variants like 'MergeOnRead'; renaming options during a version upgrade.","solutions":["Set write_mode to exactly 'merge-on-read' or 'copy-on-write' in the WITH clause","Remove the write_mode option entirely to use the default value","Check the connector documentation for the accepted literal strings (case-sensitive)","Run SHOW CREATE SINK or the sink error message to confirm which invalid value was passed"],"exampleFix":"// before\nWITH (connector = 'iceberg', write_mode = 'merge_on_read')\n// after\nWITH (connector = 'iceberg', write_mode = 'merge-on-read')","handlingStrategy":"validation","validationCode":"const VALID_WRITE_MODES: [&str; 2] = [\"merge-on-read\", \"copy-on-write\"];\nfn validate_write_mode(mode: &str) -> Result<(), String> {\n    if VALID_WRITE_MODES.contains(&mode) {\n        Ok(())\n    } else {\n        Err(format!(\n            \"invalid write_mode: {}, must be one of: merge-on-read, copy-on-write\",\n            mode\n        ))\n    }\n}","typeGuard":"fn is_valid_write_mode(s: &str) -> bool {\n    matches!(s, \"merge-on-read\" | \"copy-on-write\")\n}","tryCatchPattern":"match s.parse::<IcebergWriteMode>() {\n    Ok(mode) => mode,\n    Err(e) => {\n        // SinkError::Config: fix the WITH option string before retrying\n        return Err(e.context(\"check write_mode in WITH clause: exact literal required\"));\n    }\n}","preventionTips":["Use the exact literals 'merge-on-read' / 'copy-on-write' (kebab-case, lowercase)","Copy WITH options from RisingWave docs, not other engines' connector docs","Validate connector options with a dry-run/plan before CREATE SINK in CI","Omit write_mode when the default is acceptable"],"tags":["iceberg","config","enum-parsing","rust"],"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"}