helix-editor/helix · error · anyhow::Error

Repeated key modifier '{}-'

Error message

Repeated key modifier '{}-'

What it means

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.

Source

Thrown at helix-view/src/input.rs:430

                        suggestion
                    ));
                }
            }
            invalid => return Err(anyhow!("Invalid key code '{}'", invalid)),
        };

        let mut modifiers = KeyModifiers::empty();
        for token in tokens {
            let flag = match token {
                "S" => KeyModifiers::SHIFT,
                "A" => KeyModifiers::ALT,
                "C" => KeyModifiers::CONTROL,
                "Meta" | "Cmd" | "Win" => KeyModifiers::SUPER,
                _ => return Err(anyhow!("Invalid key modifier '{}-'", token)),
            };

            if modifiers.contains(flag) {
                return Err(anyhow!("Repeated key modifier '{}-'", token));
            }
            modifiers.insert(flag);
        }

        // Normalize character keys so that characters like C-S-r and C-R
        // are represented by equal KeyEvents.
        match code {
            KeyCode::Char(ch)
                if ch.is_ascii_lowercase() && modifiers.contains(KeyModifiers::SHIFT) =>
            {
                code = KeyCode::Char(ch.to_ascii_uppercase());
                modifiers.remove(KeyModifiers::SHIFT);
            }
            _ => (),
        }

        Ok(KeyEvent { code, modifiers })
    }

View on GitHub (pinned to 079a789e8c)

Solutions

  1. Remove the duplicate token: "C-C-a" -> "C-a".
  2. Remember Meta, Cmd, and Win are the same modifier; use only one of them per key.
  3. Run :keymap after config reload to verify the binding registered.

Example fix

# before (config.toml)
 "C-C-a" = "select_all"

# after
 "C-a" = "select_all"
Defensive patterns

Strategy: validation

Validate before calling

fn no_repeated_modifiers(spec: &str) -> bool {
    let mut seen = std::collections::HashSet::new();
    spec.split('-').filter(|t| !t.is_empty()).all(|t| seen.insert(t.to_ascii_lowercase()))
}

Try / catch

if let Err(err) = spec.parse::<KeyEvent>() {
    if err.to_string().contains("Repeated key modifier") {
        let deduped = dedup_modifier_tokens(spec); // rejoin unique tokens with '-'
        return deduped.parse::<KeyEvent>();
    }
    return Err(err);
}

Prevention

When it happens

Trigger: 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".

Common situations: 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).

Related errors


AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16). Data as JSON: /api/errors/6e1c7ade5878a5f5. Report an issue: GitHub.