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

Invalid key modifier '{}-'

Error message

Invalid key modifier '{}-'

What it means

After the key code is consumed, each remaining '-'-separated token must be a modifier: "S" (shift), "A" (alt), "C" (control), or "Meta"/"Cmd"/"Win" (super). Any other token fails with "Invalid key modifier '{token}-'". Long-form words like Ctrl, Shift, Alt are deliberately not accepted.

Source

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

                } else {
                    let suggestion = format!("{}-{}", s.trim_end_matches('-'), keys::MINUS);
                    return Err(anyhow!(
                        "Key '-' cannot be used with modifiers, use '{}' instead",
                        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);
            }
            _ => (),

View on GitHub (pinned to 079a789e8c)

Solutions

  1. Use the single letters: C for control, S for shift, A for alt; use Meta, Cmd, or Win for the super key.
  2. Order does not matter but spelling does: "C-a" not "Ctrl-a".
  3. Modifier names are case-sensitive; lowercase "c-a" is invalid.

Example fix

# before (config.toml)
 "Ctrl-s" = "write"

# after
 "C-s" = "write"
Defensive patterns

Strategy: validation

Validate before calling

const MODIFIERS: &[&str] = &["S", "A", "C", "Meta", "Cmd", "Win"];

fn modifiers_valid(spec: &str) -> bool {
    spec.split('-')
        .filter(|t| !t.is_empty())
        .take_while(|t| *t != spec.rsplit('-').next().unwrap_or(""))
        .all(|t| MODIFIERS.contains(&t))
}

Type guard

fn parse_modifier(tok: &str) -> Option<crossterm::event::KeyModifiers> {
    match tok {
        "S" => Some(KeyModifiers::SHIFT),
        "A" => Some(KeyModifiers::ALT),
        "C" => Some(KeyModifiers::CONTROL),
        "Meta" | "Cmd" | "Win" => Some(KeyModifiers::SUPER),
        _ => None,
    }
}

Try / catch

let ev = match spec.parse::<KeyEvent>() {
    Ok(ev) => ev,
    Err(err) if err.to_string().contains("Invalid key modifier") => {
        return Err(anyhow!("'{spec}': use C/S/A or Meta/Cmd/Win as modifiers"));
    }
    Err(err) => return Err(err),
};

Prevention

When it happens

Trigger: Keymap entries like "Ctrl-a", "Shift-b", "Alt-x", "ctrl-c" (case matters), or "M-x" (M is not recognized; super is Meta/Cmd/Win).

Common situations: Porting keymaps from VS Code (ctrl+...) or Emacs (M-, C- prefix styles); assuming case-insensitivity; using "Cmd" on one platform and "Win" spellings elsewhere — both fine — but "Super" is not.

Related errors


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