{"record":{"id":"6e1c7ade5878a5f5","repo":"helix-editor/helix","slug":"repeated-key-modifier","errorCode":null,"errorMessage":"Repeated key modifier '{}-'","messagePattern":"Repeated key modifier '(.+?)-'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"helix-view/src/input.rs","lineNumber":430,"sourceCode":"                        suggestion\n                    ));\n                }\n            }\n            invalid => return Err(anyhow!(\"Invalid key code '{}'\", invalid)),\n        };\n\n        let mut modifiers = KeyModifiers::empty();\n        for token in tokens {\n            let flag = match token {\n                \"S\" => KeyModifiers::SHIFT,\n                \"A\" => KeyModifiers::ALT,\n                \"C\" => KeyModifiers::CONTROL,\n                \"Meta\" | \"Cmd\" | \"Win\" => KeyModifiers::SUPER,\n                _ => return Err(anyhow!(\"Invalid key modifier '{}-'\", token)),\n            };\n\n            if modifiers.contains(flag) {\n                return Err(anyhow!(\"Repeated key modifier '{}-'\", token));\n            }\n            modifiers.insert(flag);\n        }\n\n        // Normalize character keys so that characters like C-S-r and C-R\n        // are represented by equal KeyEvents.\n        match code {\n            KeyCode::Char(ch)\n                if ch.is_ascii_lowercase() && modifiers.contains(KeyModifiers::SHIFT) =>\n            {\n                code = KeyCode::Char(ch.to_ascii_uppercase());\n                modifiers.remove(KeyModifiers::SHIFT);\n            }\n            _ => (),\n        }\n\n        Ok(KeyEvent { code, modifiers })\n    }","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/helix-editor/helix/blob/079a789e8cb08ead67f19e1971a1b7438b37354b/helix-view/src/input.rs#L412-L448","documentation":"While folding modifier tokens, from_str tracks already-set KeyModifiers flags; if the same modifier letter appears twice (modifiers.contains(flag)), it errors with \"Repeated key modifier '{token}-'\". This keeps the parsed event canonical so events like \"C-C-a\" do not create duplicate-modifier states.","triggerScenarios":"Keymap entries with a duplicated modifier token: \"C-C-a\", \"S-S-tab\", or mixed spellings that map to the same flag such as \"Cmd-Meta-x\".","commonSituations":"Copy-paste editing of bindings that duplicates a segment; trying to \"strengthen\" a shortcut by repeating the modifier; combining Meta and Cmd (both are the super flag, so \"Meta-Cmd-x\" is a repeat).","solutions":["Remove the duplicate token: \"C-C-a\" -> \"C-a\".","Remember Meta, Cmd, and Win are the same modifier; use only one of them per key.","Run :keymap after config reload to verify the binding registered."],"exampleFix":"# before (config.toml)\n \"C-C-a\" = \"select_all\"\n\n# after\n \"C-a\" = \"select_all\"","handlingStrategy":"validation","validationCode":"fn no_repeated_modifiers(spec: &str) -> bool {\n    let mut seen = std::collections::HashSet::new();\n    spec.split('-').filter(|t| !t.is_empty()).all(|t| seen.insert(t.to_ascii_lowercase()))\n}","typeGuard":null,"tryCatchPattern":"if let Err(err) = spec.parse::<KeyEvent>() {\n    if err.to_string().contains(\"Repeated key modifier\") {\n        let deduped = dedup_modifier_tokens(spec); // rejoin unique tokens with '-'\n        return deduped.parse::<KeyEvent>();\n    }\n    return Err(err);\n}","preventionTips":["De-duplicate modifier tokens when generating keymaps.","Remember Meta, Cmd, Win all map to the same super flag — use at most one."],"tags":["keymap","input","modifiers","helix","rust"],"backgroundTag":null,"analyzedSha":"079a789e8cb08ead67f19e1971a1b7438b37354b","analyzedAt":"2026-08-16T09:09:59.668Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}