{"record":{"id":"b6ee09614268372c","repo":"risingwavelabs/risingwave","slug":"unknown-match-recognize-input-mode","errorCode":null,"errorMessage":"unknown MATCH_RECOGNIZE input mode: {}","messagePattern":"unknown MATCH_RECOGNIZE input mode: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/from_proto/match_recognize.rs","lineNumber":57,"sourceCode":"\n    async fn new_boxed_executor(\n        params: ExecutorParams,\n        node: &MatchRecognizeNode,\n        store: impl StateStore,\n    ) -> StreamResult<Executor> {\n        let [input]: [_; 1] = params.input.try_into().unwrap();\n\n        // This executor's entire correctness rests on the ordered-input contract the EVENT_TIME\n        // plan (an EowcSort upstream in the same fragment) provides. A different input mode —\n        // PROCESSING_TIME is reserved, unimplemented — must fail here, not silently run against\n        // rows whose ordering guarantee does not hold.\n        // An out-of-range wire value decodes as `Unspecified` through the accessor, which would\n        // silently run an unknown future mode as event-time — the one contract this executor's\n        // correctness rests on. Reject it like every other enum in this decode path; a raw 0\n        // (genuinely unset) is accepted as event-time since this frontend always writes it.\n        if node.input_mode != 0 && node.input_mode() == MatchRecognizeInputMode::Unspecified {\n            return Err(\n                anyhow::anyhow!(\"unknown MATCH_RECOGNIZE input mode: {}\", node.input_mode).into(),\n            );\n        }\n        match node.input_mode() {\n            MatchRecognizeInputMode::Unspecified | MatchRecognizeInputMode::EventTime => {}\n            other => {\n                return Err(\n                    anyhow::anyhow!(\"unsupported MATCH_RECOGNIZE input mode: {other:?}\").into(),\n                );\n            }\n        }\n\n        let partition_key_indices = node.partition_by.iter().map(|&i| i as usize).collect();\n        // ORDER BY is carried as `ColumnOrder`. v1 only supports the default ascending order (the\n        // binder rejects anything else); assert it here too so a non-ascending plan fails fast\n        // rather than being silently sorted ascending by the executor.\n        let order_key_indices = node\n            .order_by\n            .iter()","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/from_proto/match_recognize.rs#L39-L75","documentation":"MATCH_RECOGNIZE input mode is transported as a protobuf enum. A wire value outside the known enum range decodes as `Unspecified`, which would silently be treated as event-time — the correctness contract of the executor. The decode path therefore rejects a non-zero raw value that reads back as `Unspecified`, guarding against future/unknown enum variants from newer frontends.","triggerScenarios":"`new_boxed_executor` for the MATCH_RECOGNIZE node sees `node.input_mode != 0` while the protobuf accessor maps it to `MatchRecognizeInputMode::Unspecified` — i.e. an unrecognized/out-of-range integer on the wire (e.g. a mode added by a newer frontend).","commonSituations":"Version skew: compute node older than the frontend that introduced a new input mode; corrupted or hand-edited plan protos; replaying plan fragments across versions.","solutions":["Upgrade the compute node (and all binaries) to the same version as the frontend that emitted the new input mode.","Re-generate the streaming job so the plan uses a mode the running binaries understand.","Inspect the actor proto's `input_mode` field for an out-of-range value.","If intentional, extend the executor's match arm to support the new mode before deploying it."],"exampleFix":"// before\nif node.input_mode != 0 && node.input_mode() == MatchRecognizeInputMode::Unspecified { /* reject */ }\n// after: keep the guard, but upgrade binaries so the new mode maps to a known variant\nMatchRecognizeInputMode::StreamingTime => { /* handle new mode explicitly */ }","handlingStrategy":"validation","validationCode":"// decode guard before executor construction\nif node.input_mode != 0 && node.input_mode() == MatchRecognizeInputMode::Unspecified {\n    return Err(anyhow!(\"unknown MATCH_RECOGNIZE input mode: {}\", node.input_mode));\n}","typeGuard":"fn is_known_input_mode(v: i32) -> bool {\n    MatchRecognizeInputMode::try_from(v).is_ok()\n}","tryCatchPattern":"match MatchRecognizeInputMode::try_from(node.input_mode) { Ok(m) => use(m), Err(_) => Err(anyhow!(\"unknown MATCH_RECOGNIZE input mode: {}\", node.input_mode)) }","preventionTips":["Pin all RisingWave binaries to the same release version.","Regenerate plan protos after any enum change in the schema.","Never hand-edit serialized plan fragments."],"tags":["rust","streaming","protobuf","match-recognize"],"backgroundTag":"invalid-enum-value","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"}