{"record":{"id":"529d6c2fe17b4e2c","repo":"risingwavelabs/risingwave","slug":"match-recognize-node-missing-pattern","errorCode":null,"errorMessage":"MATCH_RECOGNIZE node missing pattern","messagePattern":"MATCH_RECOGNIZE node missing pattern","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/from_proto/match_recognize.rs","lineNumber":108,"sourceCode":"        if order_key_indices.is_empty() {\n            return Err(anyhow::anyhow!(\"MATCH_RECOGNIZE plan carries an empty ORDER BY\").into());\n        }\n\n        let defines = node\n            .defines\n            .iter()\n            .map(|d| CompiledDefine::from_protobuf(d, params.eval_error_report.clone()))\n            .collect::<crate::executor::StreamExecutorResult<Vec<_>>>()?;\n        let measures = node\n            .measures\n            .iter()\n            .map(|m| CompiledMeasure::from_protobuf(m, params.eval_error_report.clone()))\n            .collect::<crate::executor::StreamExecutorResult<Vec<_>>>()?;\n\n        let pattern_node = node\n            .pattern_node\n            .as_ref()\n            .ok_or_else(|| anyhow::anyhow!(\"MATCH_RECOGNIZE node missing pattern\"))?;\n        let pattern = pattern_from_protobuf(pattern_node)\n            .map_err(|e| anyhow::anyhow!(\"invalid MATCH_RECOGNIZE pattern: {e}\"))?;\n        let nfa = Nfa::compile(&pattern);\n\n        // Fail fast on anything malformed rather than silently defaulting to PAST LAST ROW, which\n        // would mask a corrupt plan or a version skew.\n        let skip = {\n            use risingwave_pb::stream_plan::match_recognize_after_match_skip::Mode;\n            let pb_skip = node\n                .after_match_skip\n                .as_ref()\n                .ok_or_else(|| anyhow::anyhow!(\"MATCH_RECOGNIZE node missing after_match_skip\"))?;\n            let target = || {\n                pb_skip.target.clone().ok_or_else(|| {\n                    anyhow::anyhow!(\"AFTER MATCH SKIP TO FIRST/LAST missing its target variable\")\n                })\n            };\n            match pb_skip.mode() {","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/from_proto/match_recognize.rs#L90-L126","documentation":"A MATCH_RECOGNIZE plan must carry a pattern node describing the regex-like row pattern to match. `new_boxed_executor` fails with this error when `node.pattern_node` is `None`, since the executor cannot compile an NFA without a pattern. The pattern is mandatory infrastructure for the operator, so its absence indicates a corrupt or incomplete plan.","triggerScenarios":"`new_boxed_executor` calls `node.pattern_node.as_ref().ok_or_else(...)` and the protobuf oneof/optional `pattern_node` field is unset — plan serialization dropped it, the frontend never set it, or the proto was truncated/edited.","commonSituations":"Version skew where an older frontend omitted the pattern field; corrupted actor protos in-flight; tests constructing MATCH_RECOGNIZE nodes without `pattern_node`; proto schema evolution mistakes.","solutions":["Ensure the SQL MATCH_RECOGNIZE clause includes a PATTERN clause so the frontend emits `pattern_node`.","Re-create the streaming job with a frontend version matching the compute node.","Inspect the serialized actor plan and verify `pattern_node` is populated.","In tests, always set `pattern_node` via `pattern_from_protobuf`-compatible structures before building."],"exampleFix":"// before\nlet node = MatchRecognizeNode { pattern_node: None, .. };\n// after\nlet node = MatchRecognizeNode { pattern_node: Some(pattern_node_proto), .. };","handlingStrategy":"validation","validationCode":"// before building\nif node.pattern_node.is_none() {\n    return Err(anyhow!(\"MATCH_RECOGNIZE node missing pattern\"));\n}","typeGuard":"fn has_pattern(node: &MatchRecognizeNode) -> bool { node.pattern_node.is_some() }","tryCatchPattern":"let pattern_node = node.pattern_node.as_ref().ok_or_else(|| anyhow::anyhow!(\"MATCH_RECOGNIZE node missing pattern\"))?;","preventionTips":["Always write a PATTERN clause in MATCH_RECOGNIZE SQL.","Keep frontend and stream proto definitions in sync so pattern_node serializes reliably.","Add round-trip serialization tests for MATCH_RECOGNIZE nodes including the pattern."],"tags":["rust","streaming","match-recognize","plan-validation"],"backgroundTag":"missing-required-field-family","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"}