{"record":{"id":"3164fbbd3ba25389","repo":"zellij-org/zellij","slug":"invalid-keymodifier-value","errorCode":null,"errorMessage":"Invalid KeyModifier value: {}","messagePattern":"Invalid KeyModifier value: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"zellij-utils/src/ipc/enum_conversions.rs","lineNumber":137,"sourceCode":"\n// Helper functions for converting between protobuf i32 and enum types\npub fn bare_key_to_proto_i32(key: BareKey) -> i32 {\n    ProtoBareKey::from(key) as i32\n}\n\npub fn bare_key_from_proto_i32(value: i32) -> Result<BareKey> {\n    let proto_key =\n        ProtoBareKey::from_i32(value).ok_or_else(|| anyhow!(\"Invalid BareKey value: {}\", value))?;\n    proto_key.try_into()\n}\n\npub fn key_modifier_to_proto_i32(modifier: KeyModifier) -> i32 {\n    ProtoKeyModifier::from(modifier) as i32\n}\n\npub fn key_modifier_from_proto_i32(value: i32) -> Result<KeyModifier> {\n    let proto_modifier = ProtoKeyModifier::from_i32(value)\n        .ok_or_else(|| anyhow!(\"Invalid KeyModifier value: {}\", value))?;\n    proto_modifier.try_into()\n}\n","sourceCodeStart":119,"sourceCodeEnd":140,"githubUrl":"https://github.com/zellij-org/zellij/blob/5cb5df5cce4e16c5d1c57c7c062e4a90a7823c41/zellij-utils/src/ipc/enum_conversions.rs#L119-L140","documentation":"Thrown by key_modifier_from_proto_i32 (zellij-utils/src/ipc/enum_conversions.rs) when ProtoKeyModifier::from_i32 returns None: a key_modifiers entry carries an i32 that is not a valid KeyModifier discriminant. Mirror of [76] for the modifier enum; in-range-but-unset values are reported as [75] instead.","triggerScenarios":"A modifier i32 outside the Ctrl/Alt/Shift/Super/Unspecified range — newer client sending a modifier an older server lacks, handcrafted frames with arbitrary numbers, or arithmetic producing invalid discriminants.","commonSituations":"Mixed zellij versions between client and server; custom clients guessing numeric modifier codes; fuzzed or corrupted IPC input.","solutions":["Use matching zellij releases on both IPC endpoints.","Emit modifiers only via key_modifier_to_proto_i32 / `KeyModifier::X as i32`.","Guard inbound lists: validate each i32 with ProtoKeyModifier::from_i32(...).is_some() and reject the frame otherwise."],"exampleFix":"// before\nlet mods: Result<Vec<_>> = raw_mods.iter().map(|m| key_modifier_from_proto_i32(*m)).collect(); // Err(\"Invalid KeyModifier value: 42\")\n\n// after: validate before converting\nlet mods: Vec<KeyModifier> = raw_mods.iter()\n    .filter(|m| ProtoKeyModifier::from_i32(**m).is_some())\n    .map(|m| key_modifier_from_proto_i32(*m).unwrap())\n    .collect::<Result<_>>()?;","handlingStrategy":"validation","validationCode":"// validate each modifier discriminant before conversion\nlet mods: Result<Vec<KeyModifier>> = raw_mods\n    .into_iter()\n    .filter(|m| ProtoKeyModifier::from_i32(*m).is_some())\n    .map(key_modifier_from_proto_i32)\n    .collect();","typeGuard":"fn is_known_modifier(v: i32) -> bool {\n    ProtoKeyModifier::from_i32(v).is_some()\n}","tryCatchPattern":"match key_modifier_from_proto_i32(value) {\n    Ok(m) => Some(m),\n    Err(e) if e.to_string().starts_with(\"Invalid KeyModifier value\") => {\n        log::warn!(\"unknown KeyModifier discriminant {value}; entry skipped\");\n        None\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Same zellij version on every IPC endpoint; enum additions only flow forward with matching releases.","Use key_modifier_to_proto_i32 for all outbound modifiers.","Validate repeated i32 fields in one pass at the boundary and drop unknown values with a warning."],"tags":["zellij","rust","protobuf","ipc","key-modifiers","version-skew"],"backgroundTag":"invalid-enum-value","analyzedSha":"5cb5df5cce4e16c5d1c57c7c062e4a90a7823c41","analyzedAt":"2026-08-19T07:42:58.758Z","contentChangedAt":"2026-08-19T07:42:58.758Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}