risingwavelabs/risingwave · error · SinkError::Config
(dynamic: serde deserialization error from sink properties)
Error message
(dynamic: serde deserialization error from sink properties)
What it means
`from_btreemap` deserializes the sink's WITH properties into `SnowflakeV2Config` via serde. Any unknown, mistyped, or missing option fails serde deserialization, and the error is wrapped in a generic SinkError::Config with the serde message. It is the entry-point validation for all Snowflake sink properties, so most misconfigurations surface here.
Source
Thrown at src/connector/src/sink/snowflake_redshift/snowflake.rs:233
if let Some(pwd) = self.private_key_file_pwd.clone() {
connection_properties.push(("private_key_file_pwd".to_owned(), pwd));
}
}
_ => {
// This should never happen since from_btreemap validates auth_method
unreachable!(
"Invalid auth_method - should have been caught during config validation"
)
}
}
Ok((jdbc_url, connection_properties))
}
pub fn from_btreemap(properties: &BTreeMap<String, String>) -> Result<Self> {
let mut config =
serde_json::from_value::<SnowflakeV2Config>(serde_json::to_value(properties).unwrap())
.map_err(|e| SinkError::Config(anyhow!(e)))?;
if config.r#type != SINK_TYPE_APPEND_ONLY && config.r#type != SINK_TYPE_UPSERT {
return Err(SinkError::Config(anyhow!(
"`{}` must be {}, or {}",
SINK_TYPE_OPTION,
SINK_TYPE_APPEND_ONLY,
SINK_TYPE_UPSERT
)));
}
if config.r#type == SINK_TYPE_UPSERT && !config.with_s3 {
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();View on GitHub (pinned to 6469eb736d)
Solutions
- Read the serde error message appended by this error: it names the offending field/reason.
- Fix the WITH option names and values to match `SnowflakeV2Config` (e.g. `jdbc.url`, `snowflake.schema.name`).
- Diff against the documented Snowflake sink options for your RisingWave version, since options evolve between releases.
- Validate the properties map offline with `SnowflakeV2SinkConfig::from_btreemap` before creating the sink.
Example fix
// before WITH (connector='snowflake', jdbc_url='jdbc:snowflake://...'); // after WITH (connector='snowflake', snowflake.jdbc.url='jdbc:snowflake://...');
Defensive patterns
Strategy: validation
Validate before calling
match SnowflakeV2SinkConfig::from_btreemap(&props) {
Ok(cfg) => println!("config ok: {:?}", cfg),
Err(e) => eprintln!("bad snowflake sink config: {e}"),
} Try / catch
// Catch and surface the serde detail
match result {
Err(SinkError::Config(msg)) => log::error!("snowflake sink config rejected: {msg}"),
Err(e) => return Err(e),
Ok(cfg) => proceed(cfg),
} Prevention
- Read the wrapped serde message; it names the exact bad field.
- Diff options against the connector docs for your RisingWave version.
- Test property maps in a unit test with from_btreemap.
When it happens
Trigger: Creating a Snowflake sink whose properties fail `serde_json::from_value::<SnowflakeV2Config>`, e.g. unknown key `jdbc_url` instead of `jdbc.url`, wrong value type for `s3.bucket_name`, or a missing required field like `snowflake.schema.name`.
Common situations: Typos in WITH option names; using deprecated option names after connector upgrades; passing non-string/incorrectly-typed values; forgetting required Snowflake object identifiers.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- jdbc.url is required
- username is required
- `{}` must be {}, or {}
- You can't use the macro on this type
- (serde_json deserialization error)
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c26c8d7cccb8fd1e.
Report an issue: GitHub.