{"record":{"id":"51de6a6e30629947","repo":"risingwavelabs/risingwave","slug":"license-feature-redissinkstream-unavailable-erro","errorCode":null,"errorMessage":"{license Feature::RedisSinkStream unavailable error}","messagePattern":"\\{license Feature::RedisSinkStream unavailable error\\}","errorType":"validation","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/redis.rs","lineNumber":451,"sourceCode":"                        && let Some(channel_column_type) = all_map.get(channel_column)\n                        && (channel_column_type != &DataType::Varchar)\n                    {\n                        return Err(SinkError::Config(anyhow!(\n                            \"`{CHANNEL_COLUMN}` must be set to `varchar`\"\n                        )));\n                    }\n\n                    let value_format =\n                        self.format_desc.options.get(VALUE_FORMAT).ok_or_else(|| {\n                            SinkError::Config(anyhow!(\"Cannot find `{VALUE_FORMAT}`\"))\n                        })?;\n                    TemplateStringEncoder::check_string_format(value_format, &all_map)?;\n                }\n                Some(REDIS_VALUE_TYPE_STREAM) => {\n                    tracing::error!(\"test:for bug\");\n                    risingwave_common::license::Feature::RedisSinkStream\n                        .check_available()\n                        .map_err(|e| anyhow::anyhow!(e))?;\n                    let stream = self.format_desc.options.get(STREAM);\n                    let stream_column = self.format_desc.options.get(STREAM_COLUMN);\n                    if (stream.is_none() && stream_column.is_none())\n                        || (stream.is_some() && stream_column.is_some())\n                    {\n                        return Err(SinkError::Config(anyhow!(\n                            \"Please specific either `{STREAM}` or `{STREAM_COLUMN}`. They are mutually exclusive options.\"\n                        )));\n                    }\n\n                    if let Some(stream_column) = stream_column\n                        && let Some(stream_column_type) = all_map.get(stream_column)\n                        && (stream_column_type != &DataType::Varchar)\n                    {\n                        return Err(SinkError::Config(anyhow!(\n                            \"`{STREAM_COLUMN}` must be set to `varchar`\"\n                        )));\n                    }","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/redis.rs#L433-L469","documentation":"The Redis stream value type (`value type = 'stream'`) is gated behind a licensed feature, `Feature::RedisSinkStream`. During `validate`, the license check is run via `check_available()`; when the deployment lacks a valid license covering this feature, validation fails with the license feature-unavailable error message.","triggerScenarios":"Create a sink with `value type = 'stream'` on an unlicensed, expired-license, or free-tier RisingWave deployment; the check is also hit in validation even before any data flows.","commonSituations":"Developers testing stream sinks locally without a license key; enterprises whose license expired or excludes the Redis stream sink feature; the preceding `tracing::error!(\"test:for bug\")` indicates this branch was also under debugging.","solutions":["Install or renew a RisingWave enterprise license that includes the Redis stream sink feature.","Switch `value type` to `string`, `geo`, or `pubsub`, which are not license gated.","Contact RisingWave sales/support if the license should include this feature but the check still fails."],"exampleFix":"// before\nWITH (connector='redis', value type='stream', stream='alerts')  // unlicensed\n// after\nWITH (connector='redis', value type='pubsub', channel='alerts')","handlingStrategy":"fallback","validationCode":"// Query license status before creating a stream-type redis sink\nconst licensed = await checkFeature('redis_sink_stream');\nif (!licensed) useAlternativeValueType('pubsub');","typeGuard":null,"tryCatchPattern":"try { await createSink(cfg); } catch (e) { if (/unavailable|license/i.test(String(e))) { cfg['value type'] = 'string'; await createSink(cfg); } else throw e; }","preventionTips":["Verify the enterprise license covers Redis stream sink before designing around it","Monitor license expiry in deployment automation","Prefer non-gated value types in dev/test environments"],"tags":["redis","license","feature-gate"],"backgroundTag":"feature-not-enabled","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"}