{"record":{"id":"af309c62adec26f1","repo":"risingwavelabs/risingwave","slug":"write-batch-size-must-be-greater-than-0","errorCode":null,"errorMessage":"`write_batch_size` must be greater than 0","messagePattern":"`write_batch_size` must be greater than 0","errorType":"validation","errorClass":"SinkError::Config","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/turbopuffer.rs","lineNumber":102,"sourceCode":"    pub unknown_fields: std::collections::HashMap<String, String>,\n}\n\ncrate::impl_sink_unknown_fields!(TurbopufferConfig);\n\nimpl EnforceSecret for TurbopufferConfig {\n    const ENFORCE_SECRET_PROPERTIES: phf::Set<&'static str> = phf::phf_set! {\n        \"api_key\",\n    };\n}\n\nimpl TurbopufferConfig {\n    fn from_btreemap(values: BTreeMap<String, String>) -> Result<Self> {\n        let config = serde_json::from_value::<TurbopufferConfig>(\n            serde_json::to_value(values).expect(\"serialize sink properties\"),\n        )\n        .map_err(|e| SinkError::Config(anyhow!(e)))?;\n        if config.write_batch_size == 0 {\n            return Err(SinkError::Config(anyhow!(\n                \"`write_batch_size` must be greater than 0\"\n            )));\n        }\n        if config.max_linger_second == 0 {\n            return Err(SinkError::Config(anyhow!(\n                \"`max_linger_second` must be greater than 0\"\n            )));\n        }\n        if config.num_shards == Some(0) {\n            return Err(SinkError::Config(anyhow!(\n                \"`num_shards` must be greater than 0\"\n            )));\n        }\n        Ok(config)\n    }\n}\n\n#[derive(Clone, Debug)]","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/turbopuffer.rs#L84-L120","documentation":"Numeric option validation in TurbopufferConfig::from_btreemap: the `write_batch_size` option was set to 0 (or otherwise non-positive), which would make sink batches empty and stall writing. The guard enforces a strictly positive batch size when the sink config is built.","triggerScenarios":"CREATE SINK with connector='turbopuffer' and WITH option write_batch_size = '0'.","commonSituations":"Copy-pasted config with 0 placeholder; computed batch size evaluating to 0; misunderstanding of default behavior (omit the option to use default).","solutions":["Set write_batch_size to a positive integer (e.g. 500)","Remove the write_batch_size option to use the default","Validate the value before issuing CREATE SINK"],"exampleFix":"// before\nWITH (connector='turbopuffer', write_batch_size = '0')\n// after\nWITH (connector='turbopuffer', write_batch_size = '500')","handlingStrategy":"validation","validationCode":"if (props.write_batch_size !== undefined && Number(props.write_batch_size) <= 0) throw new Error('write_batch_size must be > 0')","typeGuard":"const validBatch = (n) => Number.isInteger(n) && n > 0;","tryCatchPattern":"catch (SinkError::Config(e)) if e.contains('write_batch_size') { fix option and retry DDL }","preventionTips":["Omit batch options instead of setting 0","Sanity-check generated configs for zero placeholders","Document defaults for operators"],"tags":["turbopuffer","config","validation","batch-size"],"backgroundTag":"invalid-config-value","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}