risingwavelabs/risingwave · error · SinkError
`{STREAM}` and `{STREAM_COLUMN}` only one can be set
Error message
`{STREAM}` and `{STREAM_COLUMN}` only one can be set What it means
For `redis_value_type = 'stream'` sinks with a primary key, the Redis stream target must be given via exactly one of the mutually exclusive options `stream` (static stream key) or `stream_column` (a column holding the stream key). Setting both, or neither, fails the sink build with this SinkError::Config.
Source
Thrown at src/connector/src/sink/formatter/mod.rs:395
None => {
let template = b.format_desc.options.get(VALUE_FORMAT).ok_or_else(|| {
SinkError::Config(anyhow!("Cannot find '{VALUE_FORMAT}',please set it."))
})?;
Ok(TemplateEncoder::new_string(
b.schema,
pk_indices,
template.clone(),
))
}
},
REDIS_VALUE_TYPE_STREAM => match pk_indices {
Some(_) => {
let stream = b.format_desc.options.get(STREAM).cloned();
let stream_column = b.format_desc.options.get(STREAM_COLUMN).cloned();
if (stream.is_none() && stream_column.is_none())
|| (stream.is_some() && stream_column.is_some())
{
return Err(SinkError::Config(anyhow!(
"`{STREAM}` and `{STREAM_COLUMN}` only one can be set"
)));
}
TemplateEncoder::new_pubsub_stream_key(
b.schema,
pk_indices,
stream,
stream_column,
)
}
None => {
let value_template =
b.format_desc.options.get(VALUE_FORMAT).ok_or_else(|| {
SinkError::Config(anyhow!(
"Cannot find '{VALUE_FORMAT}',please set it."
))
})?;
let key_template = b.format_desc.options.get(KEY_FORMAT).ok_or_else(|| {View on GitHub (pinned to 6469eb736d)
Solutions
- Keep exactly one of `stream = 'my-stream'` or `stream_column = 'stream_col'`; remove the other.
- Use `stream_column` for per-row dynamic stream keys, `stream` for a single fixed stream.
- Re-create the sink after cleaning the WITH options.
Example fix
// before WITH (redis_value_type='stream', stream='events', stream_column='topic'); // after WITH (redis_value_type='stream', stream_column='topic'); -- or stream='events' only
Defensive patterns
Strategy: validation
Validate before calling
if value_type == "stream" {
let s = with_options.contains_key("stream");
let sc = with_options.contains_key("stream_column");
if s == sc {
return Err("Set exactly one of `stream` or `stream_column`".into());
}
} Try / catch
match result {
Err(e) if e.to_string().contains("only one can be set") => {
eprintln!("Fix stream options (keep exactly one of stream/stream_column): {}", e);
}
other => other?,
} Prevention
- Set only one of stream / stream_column per sink
- Remove stale options when migrating sinks between static and dynamic stream keys
- Review the resolved WITH options, not just the SQL text
When it happens
Trigger: Creating a Redis stream sink with a primary key where the WITH options include both `stream` and `stream_column`, or neither of them.
Common situations: Users migrate from a pubsub sink and leave a `channel`-like mix of options behind, or they copy both a static stream name and a stream column from an example and keep both.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- `{CHANNEL}` and `{CHANNEL_COLUMN}` only one can be set
- Cannot find '{KEY_FORMAT}',please set it.
- Cannot find '{option_name}',please set it.
- Cannot find `{MEMBER_NAME}`,please set it.
- Cannot find `{KEY_FORMAT}`,please set it.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/7c4f09bde84e34c5.
Report an issue: GitHub.