moeru-ai/airi · error · Error
Invalid accelerator "${input}": no key token
Error message
Invalid accelerator "${input}": no key token What it means
After the token loop finishes, if `key` is still `undefined` (no non-modifier token was found), the parser throws `Invalid accelerator "<input>": no key token`. An accelerator must resolve to exactly one non-modifier key; a modifiers-only string is invalid.
Source
Thrown at packages/stage-shared/src/global-shortcut/accelerators.ts:340
const token = raw.trim()
if (token.length === 0)
throw new Error(`Invalid accelerator "${input}": empty token`)
const modifier = lookupModifierToken(token)
if (modifier !== undefined) {
if (modifiers.includes(modifier))
throw new Error(`Invalid accelerator "${input}": duplicate modifier "${modifier}"`)
modifiers.push(modifier)
continue
}
if (key !== undefined)
throw new Error(`Invalid accelerator "${input}": multiple non-modifier keys ("${key}", "${token}")`)
key = normalizeKeyToken(token)
}
if (key === undefined)
throw new Error(`Invalid accelerator "${input}": no key token`)
return { modifiers, key }
}
/**
* Tests whether `input` is a well-formed accelerator string.
*
* Use when:
* - Gating user input without needing the parsed result
*
* Returns:
* - `true` when `parseAccelerator` would succeed, `false` otherwise
*/
export function isValidAccelerator(input: string): boolean {
try {
parseAccelerator(input)
return true
}View on GitHub (pinned to 27111382b4)
Solutions
- Require a non-modifier key in the recorder before enabling save.
- Default unbound shortcuts to `null`, not a modifiers-only placeholder string.
- Run `isValidAccelerator(input)` and prompt the user to complete the combo.
- If building the string programmatically, assert a `key` is set before calling `formatAccelerator`/round-tripping.
Example fix
// before
const accel = mods.length ? `${mods.join('+')}` : ''
parseAccelerator(accel)
// after
if (!key) return // do not persist a modifiers-only combo
const accel = formatAccelerator({ modifiers: mods, key }) Defensive patterns
Strategy: validation
Validate before calling
const hasKey = raw.split('+').map(t => t.trim()).some(t => lookupModifierToken(t) === undefined && t.length > 0)
if (hasKey) parseAccelerator(raw) Type guard
function acceleratorHasKeyToken(input: string): boolean {
return input.split('+').map(t => t.trim()).some(t => lookupModifierToken(t) === undefined && t.length > 0)
} Try / catch
try {
parseAccelerator(raw)
} catch (e) {
if (e instanceof Error && e.message.includes('no key token')) {
// prompt user to complete the combo
} else throw e
} Prevention
- Require a non-modifier key in the recorder before enabling save.
- Default unbound shortcuts to null, not a modifiers-only placeholder.
- Run isValidAccelerator on candidate bindings.
When it happens
Trigger: Inputs such as `"Ctrl"`, `"Mod+Shift"`, `"Alt+Ctrl+Shift"`, `"Cmd"`, or any string where every token is a modifier alias.
Common situations: A keybind recorder that only captured modifier keydowns and never the final character; a partial config; user releasing the key before the recorder closed the combo; a default value that lists only modifiers as a placeholder.
Related errors
- Invalid accelerator: empty string
- Invalid accelerator "${input}": empty token
- Invalid accelerator "${input}": duplicate modifier "${modifi
- Invalid accelerator "${input}": multiple non-modifier keys (
- Invalid accelerator: unknown key "${token}"
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/3c3c47ea4413f23e.
Report an issue: GitHub.