{"record":{"id":"9caa8243f5caca47","repo":"risingwavelabs/risingwave","slug":"serde-json-deserialization-error-of-clickhouseconf","errorCode":null,"errorMessage":"serde_json deserialization error of ClickHouseConfig from properties (wrapped error)","messagePattern":"serde_json deserialization error of ClickHouseConfig from properties \\(wrapped error\\)","errorType":"validation","errorClass":"SinkError::Config","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/clickhouse.rs","lineNumber":383,"sourceCode":"    is_append_only: bool,\n}\n\nimpl EnforceSecret for ClickHouseSink {\n    fn enforce_secret<'a>(\n        prop_iter: impl Iterator<Item = &'a str>,\n    ) -> crate::error::ConnectorResult<()> {\n        for prop in prop_iter {\n            ClickHouseConfig::enforce_one(prop)?;\n        }\n        Ok(())\n    }\n}\n\nimpl ClickHouseConfig {\n    pub fn from_btreemap(properties: BTreeMap<String, String>) -> Result<Self> {\n        let config =\n            serde_json::from_value::<ClickHouseConfig>(serde_json::to_value(properties).unwrap())\n                .map_err(|e| SinkError::Config(anyhow!(e)))?;\n        if config.r#type != SINK_TYPE_APPEND_ONLY && config.r#type != SINK_TYPE_UPSERT {\n            return Err(SinkError::Config(anyhow!(\n                \"`{}` must be {}, or {}\",\n                SINK_TYPE_OPTION,\n                SINK_TYPE_APPEND_ONLY,\n                SINK_TYPE_UPSERT\n            )));\n        }\n        Ok(config)\n    }\n}\n\nimpl TryFrom<SinkParam> for ClickHouseSink {\n    type Error = SinkError;\n\n    fn try_from(param: SinkParam) -> std::result::Result<Self, Self::Error> {\n        let schema = param.schema();\n        let pk_indices = param.downstream_pk_or_empty();","sourceCodeStart":365,"sourceCodeEnd":401,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/clickhouse.rs#L365-L401","documentation":"ClickHouseConfig::from_btreemap serializes the user's WITH properties into JSON and deserializes them into ClickHouseConfig. If serde cannot deserialize the value (missing/wrongly-typed fields), the underlying serde error is wrapped in a SinkError::Config with this message.","triggerScenarios":"CREATE SINK ... WITH (connector='clickhouse', ...) where a property has an unexpected name or type, or serde_json conversion of the BTreeMap fails (e.g. non-string-derived values that violate the expected schema).","commonSituations":"Misspelled option names, wrong value types (e.g. numeric strings where bool/number expected), or unknown fields that serde's config struct rejects.","solutions":["Read the wrapped serde error (available via the error chain) to identify the offending property.","Fix option names and value types to match ClickHouseConfig's expected fields.","Remove unknown/legacy properties and re-create the sink.","Validate the full property set against the ClickHouse sink documentation before submitting."],"exampleFix":"// before\nWITH (connector='clickhouse', type='append only', url='...', ...)\n// after\nWITH (connector='clickhouse', type='append-only', url='http://...', table='t', ...)","handlingStrategy":"try-catch","validationCode":"function validateClickHouseProps(props) {\n  const required = ['type', 'url', 'table'];\n  for (const k of required) if (!(k in props)) throw new Error(`Missing ClickHouse sink property: ${k}`);\n  if (!['append-only', 'upsert'].includes(props.type)) throw new Error(`Invalid type: ${props.type}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await createSink({ connector: 'clickhouse', ...props });\n} catch (e) {\n  if (String(e.message).includes('serde_json deserialization error of ClickHouseConfig')) {\n    // inspect e.cause / error chain for the serde field error and fix properties\n  } else throw e;\n}","preventionTips":["Validate property names/types against ClickHouseConfig before submitting DDL.","Inspect the wrapped serde error chain for the exact offending field.","Remove unknown or legacy properties.","Keep a canonical property list per connector in deployment tooling."],"tags":["clickhouse","sink","serde","config"],"backgroundTag":"json-decode-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}