risingwavelabs/risingwave · error · SinkError::Config

`{}` must be {}, or {}

Error message

`{}` must be {}, or {}

What it means

After parsing the ClickHouse sink config, from_btreemap validates that the `type` property is either 'append-only' or 'upsert'. Any other value (missing or misspelled) is rejected with this message naming the option and the two allowed values.

Source

Thrown at src/connector/src/sink/clickhouse.rs:385

impl EnforceSecret for ClickHouseSink {
    fn enforce_secret<'a>(
        prop_iter: impl Iterator<Item = &'a str>,
    ) -> crate::error::ConnectorResult<()> {
        for prop in prop_iter {
            ClickHouseConfig::enforce_one(prop)?;
        }
        Ok(())
    }
}

impl ClickHouseConfig {
    pub fn from_btreemap(properties: BTreeMap<String, String>) -> Result<Self> {
        let config =
            serde_json::from_value::<ClickHouseConfig>(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
            )));
        }
        Ok(config)
    }
}

impl TryFrom<SinkParam> for ClickHouseSink {
    type Error = SinkError;

    fn try_from(param: SinkParam) -> std::result::Result<Self, Self::Error> {
        let schema = param.schema();
        let pk_indices = param.downstream_pk_or_empty();
        let config = ClickHouseConfig::from_btreemap(param.properties)?;
        Ok(Self {

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Set type='append-only' for insert-only ClickHouse sinks.
  2. Set type='upsert' for upsert sinks (also requires primary_key).
  3. Check exact spelling/casing against the constants SINK_TYPE_APPEND_ONLY / SINK_TYPE_UPSERT.

Example fix

// before
WITH (connector='clickhouse', type='append_only', ...)
// after
WITH (connector='clickhouse', type='append-only', ...)
Defensive patterns

Strategy: validation

Validate before calling

if (!['append-only', 'upsert'].includes(props.type)) throw new Error(`ClickHouse sink type must be 'append-only' or 'upsert', got: ${props.type}`);

Prevention

When it happens

Trigger: ClickHouse CREATE SINK where the `type` property is absent or set to something other than SINK_TYPE_APPEND_ONLY ('append-only') or SINK_TYPE_UPSERT ('upsert').

Common situations: Typo like 'append_only' (underscore) or 'upsert-only', omitting `type` altogether, or copying `type` values valid for other connectors.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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