{"record":{"id":"3b7dce5342e25bd0","repo":"risingwavelabs/risingwave","slug":"cannot-find-key-format-please-set-it-or-use-j","errorCode":null,"errorMessage":"Cannot find '{KEY_FORMAT}', please set it or use JSON","messagePattern":"Cannot find '(.+?)', please set it or use JSON","errorType":"validation","errorClass":"SinkError::Config","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/redis.rs","lineNumber":353,"sourceCode":"            .iter()\n            .enumerate()\n            .filter(|(k, _)| self.pk_indices.contains(k))\n            .map(|(_, v)| (v.name.clone(), v.data_type.clone()))\n            .collect();\n        if matches!(\n            self.format_desc.encode,\n            super::catalog::SinkEncode::Template\n        ) {\n            match self\n                .format_desc\n                .options\n                .get(REDIS_VALUE_TYPE)\n                .map(|s| s.as_str())\n            {\n                // if not set, default to string\n                Some(REDIS_VALUE_TYPE_STRING) | None => {\n                    let key_format = self.format_desc.options.get(KEY_FORMAT).ok_or_else(|| {\n                        SinkError::Config(anyhow!(\n                            \"Cannot find '{KEY_FORMAT}', please set it or use JSON\"\n                        ))\n                    })?;\n                    TemplateStringEncoder::check_string_format(key_format, &pk_map)?;\n                    let value_format =\n                        self.format_desc.options.get(VALUE_FORMAT).ok_or_else(|| {\n                            SinkError::Config(anyhow!(\n                                \"Cannot find `{VALUE_FORMAT}`, please set it or use JSON\"\n                            ))\n                        })?;\n                    TemplateStringEncoder::check_string_format(value_format, &all_map)?;\n                }\n                Some(REDIS_VALUE_TYPE_GEO) => {\n                    let key_format = self.format_desc.options.get(KEY_FORMAT).ok_or_else(|| {\n                        SinkError::Config(anyhow!(\n                            \"Cannot find '{KEY_FORMAT}', please set it or use JSON\"\n                        ))\n                    })?;","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/redis.rs#L335-L371","documentation":"When creating a Redis sink with template encoding and value type `string` (the default), RisingWave requires a `key_format` option that defines the template used to build the Redis key. The sink's `validate` step throws this SinkError::Config when the `key_format` option is absent from the FORMAT ... ENCODE ... options clause, telling the user to either set it or switch to a JSON-based encoding.","triggerScenarios":"Creating a Redis sink with ENCODE TEMPLATE whose `redis_value_type` is `string` or unset, while the options map contains no `key_format` entry; validation runs at CREATE SINK time via RedisSink::validate (src/connector/src/sink/redis.rs:352).","commonSituations":"Forgetting the `key_format='...'` option in CREATE SINK ... WITH (connector = 'redis'); copying examples that use JSON encoding into a template-encoding sink; renaming the option (e.g. `key.template`) by mistake.","solutions":["Add `key_format = '<template>'` to the ENCODE TEMPLATE options, e.g. key_format = 'prefix::{pk}' alongside value_format","Alternatively switch the sink to a JSON encoding which does not require key_format","Ensure the option key is spelled exactly `key_format` (lowercase with underscore)"],"exampleFix":"-- before\nCREATE SINK s FROM mv WITH (connector='redis', redis.url='redis://127.0.0.1:6379', format template, encode template (value_format = 'f={v}'));\n-- after\nCREATE SINK s FROM mv WITH (connector='redis', redis.url='redis://127.0.0.1:6379', format template, encode template (key_format = 'kv::{pk}', value_format = 'f={v}'));","handlingStrategy":"validation","validationCode":"-- ensure options contains key_format before CREATE SINK (template encoding, string value type)\n-- options.contains_key(\"key_format\")","typeGuard":null,"tryCatchPattern":"match result.err() { Some(e) if e.contains(\"key_format\") => add_missing_option(\"key_format\"), _ => propagate(result) }","preventionTips":["Always include key_format in ENCODE TEMPLATE options for Redis string sinks","Copy the full documented WITH clause template from RisingWave docs rather than building options piecemeal","Create the sink in a dev environment first so validate() catches missing options before production"],"tags":["redis","sink","configuration","missing-option"],"backgroundTag":"missing-required-config-field","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}