risingwavelabs/risingwave · error · SinkError::Config
`task.target_completion_interval` requires…
Error message
`task.target_completion_interval` requires `task.serverless` to be true
What it means
`task.target_completion_interval` only tunes a serverless Snowflake task; from_btreemap rejects setting it when `task.serverless` is not true. Without serverless tasks the interval would be silently meaningless, so the connector fails fast instead.
Solutions
- Add `task.serverless = true` to the WITH options
- Remove `task.target_completion_interval` if you intend to use a regular warehouse-based task
Example fix
// before WITH (connector='snowflake', type='upsert', with_s3=true, task.target_completion_interval='15m'); // after WITH (connector='snowflake', type='upsert', with_s3=true, task.serverless=true, task.target_completion_interval='15m');
Defensive patterns
Strategy: validation
Validate before calling
if options.contains_key("task.target_completion_interval") && options.get("task.serverless").map(|v| v.as_str()) != Some("true") {
return Err("task.target_completion_interval requires task.serverless = true");
} Prevention
- Always set task.serverless=true when tuning target_completion_interval
- Copy tuning options from serverless examples only
- Validate the full WITH clause against the docs before CREATE SINK
When it happens
Trigger: Creating a Snowflake upsert sink with `task.target_completion_interval` set while `task.serverless` is false or absent.
Common situations: Copying a serverless-task tuning snippet into a sink config that uses a regular warehouse; adding the interval option but forgetting to flip task.serverless to true.
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
- `intermediate.table.name`, `write.target.interval.seconds`…
- Snowflake upsert sinks require `with_s3 = true` so all CDC…
- `task.serverless` must not be combined with `warehouse`
- auth.method=key_pair_file must not set `password`
- auth.method=key_pair_file must not set `private_key_pem`
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/9777704f999d7ee1.
Report an issue: GitHub.
Appendix: source
Thrown at src/connector/src/sink/snowflake_redshift/snowflake.rs:261
return Err(SinkError::Config(anyhow!(
"Snowflake upsert sinks require `with_s3 = true` so all CDC rows are loaded by the serialized COPY INTO task"
)));
}
let has_upsert_task_config = config.snowflake_cdc_table_name.is_some()
|| properties.contains_key("write.target.interval.seconds")
|| config.snowflake_warehouse.is_some()
|| config.task_serverless
|| config.task_target_completion_interval.is_some();
if config.r#type != SINK_TYPE_UPSERT && has_upsert_task_config {
return Err(SinkError::Config(anyhow!(
"`intermediate.table.name`, `write.target.interval.seconds`, `warehouse`, \
`task.serverless`, and `task.target_completion_interval` require `{}` = {}",
SINK_TYPE_OPTION,
SINK_TYPE_UPSERT
)));
}
if config.task_target_completion_interval.is_some() && !config.task_serverless {
return Err(SinkError::Config(anyhow!(
"`task.target_completion_interval` requires `task.serverless` to be true"
)));
}
if config.task_serverless && config.snowflake_warehouse.is_some() {
return Err(SinkError::Config(anyhow!(
"`task.serverless` must not be combined with `warehouse`"
)));
}
// Normalize and validate authentication method
let has_password = config.password.is_some();
let has_file = config.private_key_file.is_some();
let has_pem = config.private_key_pem.as_deref().is_some();
let normalized_auth_method = match config
.auth_method
.as_deref()
.map(|s| s.trim().to_ascii_lowercase())View on GitHub (pinned to 6469eb736d)