zed-industries/zed · warning · anyhow::Error
Cannot remove a keybinding that does not exist
Error message
Cannot remove a keybinding that does not exist
What it means
remove_keybinding walks the user keymap file to delete the entry matching a ProcessedBinding; the removal machinery matches on keystrokes, so a binding with no keystrokes (existing.keystrokes() == None) cannot be located and the function refuses rather than corrupting the file.
Source
Thrown at crates/keymap_editor/src/keymap_editor.rs:3697
.context("Failed to write keymap file")?;
telemetry::event!(
"Keybinding Updated",
new_keybinding = new_keybinding,
removed_keybinding = removed_keybinding,
source = source
);
Ok(())
}
async fn remove_keybinding(
existing: ProcessedBinding,
fs: &Arc<dyn Fs>,
keyboard_mapper: &dyn PlatformKeyboardMapper,
deprecated_aliases: &HashMap<&'static str, &'static str>,
) -> anyhow::Result<()> {
let Some(keystrokes) = existing.keystrokes() else {
anyhow::bail!("Cannot remove a keybinding that does not exist");
};
let keymap_contents = settings::KeymapFile::load_keymap_file(fs)
.await
.context("Failed to load keymap file")?;
let tab_size = infer_json_indent_size(&keymap_contents);
let operation = settings::KeybindUpdateOperation::Remove {
target: settings::KeybindUpdateTarget {
context: existing.context().and_then(KeybindContextString::local_str),
keystrokes,
action_name: existing.action().name,
action_arguments: existing
.action()
.arguments
.as_ref()
.map(|arguments| arguments.text.as_ref()),
},
target_keybind_source: existing.keybind_source().unwrap_or(KeybindSource::User),View on GitHub (pinned to 9d272b0363)
Solutions
- Only enable 'Remove keybinding' UI actions when the selected binding has keystrokes
- For bindings that live in the default keymap, add an overriding entry instead of removing
- Edit the user keymap.json directly (via keymap editor open-file) to delete the stale block
- Check whether the binding came from a bundled keymap that the removal flow cannot modify by design
Example fix
// before
let Some(keystrokes) = existing.keystrokes() else {
anyhow::bail!("Cannot remove a keybinding that does not exist");
};
// after (caller gates the action)
let can_remove = existing.keystrokes().is_some();
// ... .when(can_remove, |row| row.mouse_listeners(...)) Defensive patterns
Strategy: validation
Validate before calling
let Some(keystrokes) = binding.keystrokes() else {
// nothing to match in the keymap file; hide the remove affordance
return Ok(());
}; Type guard
fn is_removable_binding(b: &ProcessedBinding) -> bool { b.keystrokes().is_some() } Prevention
- Gate remove/delete UI on the binding actually having keystrokes
- Read back and re-parse the keymap file after edits to catch structural drift
- Prefer additive overrides when a binding cannot be matched for removal
When it happens
Trigger: The remove flow invoked on a binding that carries no keystrokes — e.g. an action-only entry or a partially constructed binding object — so the KeybindUpdateOperation::Remove target would have nothing to match against in the JSON.
Common situations: UI race where the binding list was refreshed mid-edit; entries synthesized from defaults rather than user keymap contents; stale code paths calling remove on non-keystroke bindings.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- extension dir {} is not an absolute path
- Zed cannot determine how to run this debug scenario. `build`
- Action name is required
- failed to compile {} parser with clang: {}
- grammar directory '{}' already exists, but is not a git clon
AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-08-20).
Data as JSON: /api/errors/8563a567249f8596.
Report an issue: GitHub.