risingwavelabs/risingwave · error · SinkError::Config
(dynamic serde_json deserialization error for Turbopuffer si
Error message
(dynamic serde_json deserialization error for Turbopuffer sink properties)
What it means
TurbopufferConfig::from_btreemap deserializes the sink's properties map into TurbopufferConfig via JSON round-trip; serde reports missing/invalid fields, and the sink wraps it as a Config error. It means required sink WITH options are missing or have wrong types.
Source
Thrown at src/connector/src/sink/turbopuffer.rs:100
#[serde(flatten)]
pub unknown_fields: std::collections::HashMap<String, String>,
}
crate::impl_sink_unknown_fields!(TurbopufferConfig);
impl EnforceSecret for TurbopufferConfig {
const ENFORCE_SECRET_PROPERTIES: phf::Set<&'static str> = phf::phf_set! {
"api_key",
};
}
impl TurbopufferConfig {
fn from_btreemap(values: BTreeMap<String, String>) -> Result<Self> {
let config = serde_json::from_value::<TurbopufferConfig>(
serde_json::to_value(values).expect("serialize sink properties"),
)
.map_err(|e| SinkError::Config(anyhow!(e)))?;
if config.write_batch_size == 0 {
return Err(SinkError::Config(anyhow!(
"`write_batch_size` must be greater than 0"
)));
}
if config.max_linger_second == 0 {
return Err(SinkError::Config(anyhow!(
"`max_linger_second` must be greater than 0"
)));
}
if config.num_shards == Some(0) {
return Err(SinkError::Config(anyhow!(
"`num_shards` must be greater than 0"
)));
}
Ok(config)
}
}View on GitHub (pinned to 6469eb736d)
Solutions
- Check the error detail for which field failed (missing field 'x' / invalid type) and add/fix that WITH property
- Verify against current Turbopuffer sink docs for required property names
- Quote string values correctly in the CREATE SINK statement
Example fix
// before WITH (connector = 'turbopuffer', region = 'aws-us-east-1') // missing api_key // after WITH (connector = 'turbopuffer', region = 'aws-us-east-1', api_key = '...', namespace_column = 'ns');
Defensive patterns
Strategy: validation
Validate before calling
const required = ['api_key','region']; const missing = required.filter(k => !(k in props)); if (missing.length) throw new Error('missing: ' + missing) Type guard
const isTurbopufferConfig = (c) => typeof c?.api_key === 'string' && typeof c?.region === 'string';
Try / catch
catch (SinkError::Config(e)) { read serde detail (missing field / invalid type) and fix the WITH option } Prevention
- Validate all required WITH options before CREATE SINK
- Keep option names in sync with current connector docs
- Test sink DDL in a dev environment first
When it happens
Trigger: CREATE SINK ... WITH (connector='turbopuffer', ...) where required properties (e.g. api_key, namespace_column, region) are missing or have wrong types.
Common situations: Typo in property name; missing api key; passing numeric options as wrong JSON type; stale property names after connector updates.
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/427f58c5f7ca51d1.
Report an issue: GitHub.