{"record":{"id":"cb2c83e059d1ad33","repo":"BloopAI/vibe-kanban","slug":"no-key-binding-found-for-action-action-in-scope","errorCode":null,"errorMessage":"No key binding found for action ${action} in scope ${scope}","messagePattern":"No key binding found for action (.+?) in scope (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/web-core/src/shared/keyboard/useSemanticKey.ts","lineNumber":71,"sourceCode":"      {\n        enabled,\n        enableOnContentEditable,\n        enableOnFormTags,\n        preventDefault,\n        scopes: scope ? [scope] : ['*'],\n      },\n      [\n        keys,\n        scope,\n        enableOnContentEditable,\n        enableOnFormTags,\n        preventDefault,\n        handler,\n        isEnabled,\n      ]\n    );\n\n    if (keys.length === 0) {\n      console.warn(\n        `No key binding found for action ${action} in scope ${scope}`\n      );\n    }\n  };\n}\n","sourceCodeStart":53,"sourceCodeEnd":78,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/packages/web-core/src/shared/keyboard/useSemanticKey.ts#L53-L78","documentation":"`createSemanticHook` builds keyboard shortcut hooks on top of a central keybinding registry. At hook execution it calls `getKeysFor(action, scope)`; if the registry has no keys registered for that action (in the given scope), the hook binds nothing and emits this console.warn. It is a developer-facing diagnostic, not a thrown exception — the handler simply never fires.","triggerScenarios":"Calling a semantic hook (useKeySubmit, useKeyCreate, useKeyExit, useKeyFocusSearch, useKeyNavUp, useKeyNavDown, etc.) with a scope in which the action has no registered keybinding; a typo'd action name; registry not yet populated/initialized when the hook mounts.","commonSituations":"Passing a custom scope string that has no scoped bindings registered; forgetting to register the action in the keyboard registry; action renamed in the registry but not in hook call sites; hotkey config loaded async after mount.","solutions":["Check the keyboard registry for the action's binding and register keys for it (globally or for the passed scope).","Remove or fix the `scope` option so it matches a scope where the action has bindings, or omit scope to use defaults.","Verify the action name passed to the hook matches the Action union value in the registry (fix typos/renames).","If bindings are registered dynamically, ensure registration happens before the component using the hook mounts."],"exampleFix":"// before\nuseKeySubmit(save, { scope: Scope.KanbanBoard }); // no submit binding in KanbanBoard scope\n\n// after\nuseKeySubmit(save); // uses default scope where 'submit' is registered\n// or register: registerKeys('submit', [{ key: 'mod+enter' }], Scope.KanbanBoard)","handlingStrategy":"fallback","validationCode":"import { getKeysFor, Action, Scope } from '@/shared/keyboard/registry';\nexport function assertBinding(action: Action, scope?: Scope) {\n  if (getKeysFor(action, scope).length === 0) {\n    throw new Error(`Action \"${action}\" has no key binding${scope ? ` in scope ${scope}` : ''}`);\n  }\n}","typeGuard":"function hasBinding(action: Action, scope?: Scope): boolean {\n  return getKeysFor(action, scope).length > 0;\n}","tryCatchPattern":"try {\n  assertBinding('submit', scope);\n  useKeySubmit(save, { scope });\n} catch (e) {\n  console.error('Keybinding misconfiguration:', e);\n  // fall back to an explicit button affordance so the feature still works\n}","preventionTips":["Register every action in the keyboard registry before any component using its semantic hook mounts.","Derive hook action names from the Action union type instead of raw strings to catch typos at compile time.","Add a dev-mode test that iterates all actions and asserts at least one default binding exists.","Avoid passing ad-hoc scope values unless bindings for that scope are registered."],"tags":["keyboard","hotkeys","configuration"],"backgroundTag":"missing-key-binding","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}