{"record":{"id":"ffeccf8ad7ec1b59","repo":"risingwavelabs/risingwave","slug":"channel-and-channel-column-only-one-can-be","errorCode":null,"errorMessage":"`{CHANNEL}` and `{CHANNEL_COLUMN}` only one can be set","messagePattern":"`(.+?)` and `(.+?)` only one can be set","errorType":"validation","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/formatter/mod.rs","lineNumber":366,"sourceCode":"                }\n                None => {\n                    let lat_name = b.format_desc.options.get(LAT_NAME).ok_or_else(|| {\n                        SinkError::Config(anyhow!(\"Cannot find `{LAT_NAME}`, please set it.\"))\n                    })?;\n                    let lon_name = b.format_desc.options.get(LON_NAME).ok_or_else(|| {\n                        SinkError::Config(anyhow!(\"Cannot find `{LON_NAME}`,please set it.\"))\n                    })?;\n                    TemplateEncoder::new_geo_value(b.schema, pk_indices, lat_name, lon_name)\n                }\n            },\n            REDIS_VALUE_TYPE_PUBSUB => match pk_indices {\n                Some(_) => {\n                    let channel = b.format_desc.options.get(CHANNEL).cloned();\n                    let channel_column = b.format_desc.options.get(CHANNEL_COLUMN).cloned();\n                    if (channel.is_none() && channel_column.is_none())\n                        || (channel.is_some() && channel_column.is_some())\n                    {\n                        return Err(SinkError::Config(anyhow!(\n                            \"`{CHANNEL}` and `{CHANNEL_COLUMN}` only one can be set\"\n                        )));\n                    }\n                    TemplateEncoder::new_pubsub_stream_key(\n                        b.schema,\n                        pk_indices,\n                        channel,\n                        channel_column,\n                    )\n                }\n                None => {\n                    let template = b.format_desc.options.get(VALUE_FORMAT).ok_or_else(|| {\n                        SinkError::Config(anyhow!(\"Cannot find '{VALUE_FORMAT}',please set it.\"))\n                    })?;\n                    Ok(TemplateEncoder::new_string(\n                        b.schema,\n                        pk_indices,\n                        template.clone(),","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/formatter/mod.rs#L348-L384","documentation":"For `redis_value_type = 'pubsub'` sinks with a primary key, the Redis channel target must be specified via exactly one of the two mutually exclusive options `channel` (a static channel name) or `channel_column` (a column whose value is the channel). Setting neither, or setting both, makes the sink build fail with this SinkError::Config.","triggerScenarios":"Creating a Redis pubsub sink with a primary key where the WITH options contain both `channel` and `channel_column`, or neither of them.","commonSituations":"Users add `channel` while an earlier `channel_column` option is still present, or they assume a default channel exists and provide neither option.","solutions":["Choose one channel strategy: either a fixed `channel = 'my-channel'` or `channel_column = 'channel_col'`, and delete the other option.","If you want dynamic per-row channels, keep only `channel_column`; for a fixed channel keep only `channel`.","Re-run the CREATE SINK statement after cleaning up the WITH options."],"exampleFix":"// before\nWITH (redis_value_type='pubsub', channel='alerts', channel_column='ch');\n// after\nWITH (redis_value_type='pubsub', channel_column='ch');  -- or keep channel='alerts' only","handlingStrategy":"validation","validationCode":"if value_type == \"pubsub\" {\n    let c = with_options.contains_key(\"channel\");\n    let cc = with_options.contains_key(\"channel_column\");\n    if c == cc {\n        return Err(\"Set exactly one of `channel` or `channel_column`\".into());\n    }\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"only one can be set\") => {\n        eprintln!(\"Fix channel options (keep exactly one of channel/channel_column): {}\", e);\n    }\n    other => other?,\n}","preventionTips":["Never combine channel and channel_column in one sink","Remove leftover options when converting between fixed and per-row channels","Read the full WITH clause before CREATE SINK, including generated defaults"],"tags":["redis","sink","pubsub","configuration","conflicting-options"],"backgroundTag":"conflicting-config-options","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"}