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

  1. Read the serde error message appended by this error: it names the offending field/reason.
  2. Fix the WITH option names and values to match `SnowflakeV2Config` (e.g. `jdbc.url`, `snowflake.schema.name`).
  3. Diff against the documented Snowflake sink options for your RisingWave version, since options evolve between releases.
  4. 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

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


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/c26c8d7cccb8fd1e. Report an issue: GitHub.