moeru-ai/airi · error · Error

Invalid accelerator: unknown key

Error message

Invalid accelerator: unknown key "${token}"

What it means

normalizeAcceleratorToken (packages/stage-shared/src/global-shortcut/accelerators.ts:270) maps an accelerator token to a canonical ShortcutKey: it checks named key aliases (F-keys, arrows, etc.), then single letters (Key + uppercase) and single digits (Digit + n). If every lookup misses, this error is thrown: the token is not any known key name or alias.

Solutions

  1. Use canonical names/aliases the library knows: 'A'-'Z', '0'-'9', or the named keys defined in the alias map (e.g. 'ArrowUp', 'F1'-'F12', 'Escape')
  2. Print ShortcutKey / MODIFIER_ALIASES keys from the module to see accepted tokens for your version
  3. Wrap parseAccelerator in try/catch when input comes from users, and reject with a validation message

Example fix

// before
parseAccelerator('Mod+Shift+PrtSc') // throws: unknown key
// after
parseAccelerator('Mod+Shift+P')
Defensive patterns

Strategy: validation

Validate before calling

const KEY_TOKEN_RE = /^(F([1-9]|1[0-2])|Arrow(Up|Down|Left|Right)|Escape|Enter|Tab|Backspace|Delete|Space|[A-Z]|[0-9])$/i

function isValidKeyToken(token: string): boolean {
  return KEY_TOKEN_RE.test(token)
}

Type guard

function isParsableAccelerator(input: string): boolean {
  if (input.trim().length === 0) return false
  return input.split('+').every(raw => {
    const token = raw.trim()
    return token.length > 0 && (lookupModifierToken(token) !== undefined || KEY_TOKEN_RE.test(token))
  })
}

Try / catch

try {
  registerGlobalShortcut(parseAccelerator(userShortcut), handler)
}
catch (error) {
  if (error instanceof Error && error.message.startsWith('Invalid accelerator')) {
    markShortcutInvalid(userShortcut) // surface a validation error to the user
    return
  }
  throw error
}

Prevention

When it happens

Trigger: Calling parseAccelerator with an unsupported key such as 'PrtSc', 'Space' (if not in the alias map), 'F13+', or a typo like 'KyK' or 'Commad+K'. Note '+' is the separator, so it can never itself be a token.

Common situations: User-configurable shortcut strings from settings files or stored profiles, cross-platform shortcuts copied from other apps whose key names (e.g. 'PrintScreen', 'NUM0') differ from this library's aliases.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/10b6f8b818452324. Report an issue: GitHub.

Appendix: source

Thrown at packages/stage-shared/src/global-shortcut/accelerators.ts:270

    return token

  const aliased = KEY_ALIASES.get(token)
  if (aliased !== undefined)
    return aliased

  if (SINGLE_LETTER_RE.test(token)) {
    const candidate = `Key${token.toUpperCase()}`
    if (LETTER_KEYS.has(candidate))
      return candidate
  }

  if (SINGLE_DIGIT_RE.test(token)) {
    const candidate = `Digit${token}`
    if (DIGIT_KEYS.has(candidate))
      return candidate
  }

  throw new Error(`Invalid accelerator: unknown key "${token}"`)
}

/**
 * Returns the canonical modifier for a token, or `undefined` if the
 * token is not a modifier (i.e. probably a key).
 */
function lookupModifierToken(token: string): ShortcutModifier | undefined {
  return MODIFIER_ALIASES.get(token.toLowerCase())
}

/**
 * Parses a string accelerator into its canonical structured form.
 *
 * Use when:
 * - Accepting an accelerator from author code, settings UI, or config
 *   file
 * - Validating user input
 *

View on GitHub (pinned to 677329427f)