Chrome extension keyboard shortcut checker
Paste the manifest.json of your extension, or only its "commands" object. The checker reads each suggested_key the way Chromium's manifest parser does. For each command it shows Pass or Fail on Windows, macOS, Linux and ChromeOS. For each Fail it shows the error text that Chromium uses. It also lists commands that suggest the same shortcut, and it counts the shortcuts toward the limit of 4.
The check runs in your browser. The checker does not send your text over the network. A Pass means that the parser accepts the commands block. It does not mean that Chrome will assign each shortcut (see Limits). The rules come from Chromium source files at commit aa08c55 and from the commands reference page on developer.chrome.com (see Sources). Where the two do not agree, the checker follows the source.
Why four systems? Chrome checks the commands block on the system it runs on, and some rules depend on that system. For example, "chromeos": "Ctrl+Shift+Search+Y" passes on ChromeOS. On Windows, macOS and Linux the same entry stops the extension from loading, because there a shortcut can have only 3 parts.
Check your commands block
Example: {"commands": {"toggle": {"suggested_key": "Ctrl+Shift+Y", "description": "Toggle the panel"}}}
Test one shortcut
Type the shortcut as it would appear in the manifest, for example Alt+Shift+P. Key names are case sensitive.
How the checker decides
- Input. Chrome reads
manifest.jsonwith options that allow//and/* */comments, line breaks inside strings and\xNNescapes, but not a comma after the last item (file_util.cc line 335, json_file_value_serializer.h line 66, json_reader.h lines 50-84). The checker accepts the same three extensions to strict JSON. It treats the text as a whole manifest when it has amanifest_versionkey, or a"commands"key whose value does not look like a single command. Otherwise it treats the text as the"commands"object itself. A manifest without a"commands"key is valid. An empty"commands"object is valid too. - Four systems. Chromium picks the entry for the system it runs on (
windows,mac,linuxorchromeos). When that entry is missing, it usesdefault. The checker runs the parser once for each of the four systems. - Every entry counts. Chromium parses every entry of
suggested_keyon every system. An error in themacentry also stops the extension from loading on Windows. - First error. Chrome stops at the first error in the
commandsblock and reports only that error. The checker checks every command and every entry. It then marks the error that Chrome reports first on each system. - The limit of 4. On each system the checker counts the commands whose shortcut is not a media key. Action commands such as
_execute_actioncount too. A fifth counted command is a Fail. - Conflicts. Two commands conflict when they give the same key combination on the same system. The order of the keys does not matter:
Shift+Ctrl+Yis the same asCtrl+Shift+Y. A conflict is not a Fail. Chrome loads the extension, but it does not assign the shortcut to the second command in its order (named commands in name order, then action commands).
The rules in the Chromium source
Each row names the file and the lines at commit aa08c55cb412681fb8d660739545334b4764bb69. All files were fetched on 2026-10-30.
| Rule | What the source does | Source |
|---|---|---|
| Shape | The value of "commands" must be an object, and each command must be an object. Otherwise the error is Invalid value for 'commands'. or Contents of 'commands[N]' invalid. | commands_handler.cc lines 73-94 |
| Description | Each command needs a description that is a string and not empty. The three action commands _execute_action, _execute_browser_action and _execute_page_action do not need one. | command.cc lines 144-165 |
| suggested_key | A string is the shortcut for all systems. An object gives one entry per platform key, and each value must be a string that is not empty (else the error ends in Missing.). Without suggested_key the command has no shortcut. | command.cc lines 173-200 |
| Platform keys | Only windows, mac, chromeos, linux and default, in lower case. Any other key, for example ios or Windows, stops the extension from loading. | ui/.../command.cc lines 215-223 |
| Entry for the system | Chromium uses the entry for its own system, else default. With neither, the error is Could not find key specification ... | command.cc lines 231-241 |
| Command and Option | These two names are allowed only in the mac entry. In any other entry, default included, the extension does not load on any system. | command.cc lines 205-229 |
| macOS names | In the mac entry, and in default when Chrome runs on macOS, Ctrl becomes Command, MacCtrl becomes Ctrl and Option becomes Alt. So MacCtrl in default works only on macOS. | command.cc lines 43-66 |
| Number of keys | The shortcut is split at +. Spaces around each part are ignored, but not spaces inside a part, so Page Up is not PageUp. At most 3 parts, or 4 when Chrome runs on ChromeOS. | ui/.../command.cc lines 28-34 and 225-234 |
| Key names | Exactly one key: A-Z, 0-9, Comma, Period, Up, Down, Left, Right, Insert, Delete, Home, End, PageUp, PageDown, Space, Tab, or a media key. Names are case sensitive. F1, Escape and Enter are not in the list. | ui/.../command.cc lines 275-338 |
| Modifiers | Ctrl, Alt and Shift. Command only in the mac entry. Search only in the chromeos entry. | ui/.../command.cc lines 239-274 |
| Modifier rule | Each key except a media key needs a modifier. Shift alone is not enough. Alt together with Ctrl, Command or Search is not allowed. | ui/.../command.cc lines 36-68 |
| Media keys | MediaNextTrack, MediaPlayPause, MediaPrevTrack and MediaStop must stand alone. Ctrl, Alt, Command or Search with a media key gives the error Media key cannot have any modifier .... Two cases get the general Invalid value ... error instead: Alt together with Ctrl, Command or Search, and Shift as the only modifier. An action command cannot use a media key. | ui/.../command.cc lines 342-354; command.cc lines 257-259 |
| Limit of 4 | The parser counts commands, not entries. A command counts when its shortcut on the running system is not a media key. Action commands count. The fifth counted command gives Too many shortcuts specified for 'commands': The maximum is 4. An API permission with the ID kCommandsAccessibility lifts the limit. | commands_handler.cc lines 25-27 and 100-116 |
| Action commands | _execute_action needs an "action" key in the manifest, _execute_browser_action needs "browser_action" and _execute_page_action needs "page_action". Without it, Chromium adds a warning and ignores the command. Other names that start with _ are parsed and then dropped. | commands_handler.cc lines 121-145 |
| Same shortcut twice | The parser has no rule about it. When Chrome assigns the suggested keys, it skips a key that is already taken. It assigns the named commands first, in name order, and then the action commands. | command_service.cc lines 236-244 and 494-537 |
| Global commands | The parser reads "global": true and checks nothing more. Chrome assigns a global shortcut only when it is Ctrl+Shift plus a digit (Command+Shift plus a digit on macOS), when it is a media key, or when the extension has the kCommandsAccessibility permission. It does not assign the key of an action command that has "global": true. Other global shortcuts load but are not assigned. | command_service.cc lines 540-576 |
Where the documentation and the source do not agree
The left column quotes the commands reference page (last updated 2026-10-29). The middle column links the Chromium source at commit aa08c55. In each case the checker follows the source.
| Documentation | Chromium source | What the checker does |
|---|---|---|
The "General" key list is "Comma, Period, Home, End, PageUp, PageDown, Space, Insert, Delete". No key list on the page names Tab. | ui/.../command.cc line 282 accepts Tab as a key. | "suggested_key": "Ctrl+Shift+Tab" gets Pass on all four systems. |
"Extension command shortcuts must include either Ctrl or Alt." | ui/.../command.cc lines 48-68 ask for any modifier and reject Shift alone. Search in the chromeos entry counts as a modifier on its own. (The documentation itself allows Command and MacCtrl in place of Ctrl on macOS.) | The entry "chromeos": "Search+Y" passes on all four systems. On Windows, macOS and Linux the command also needs a default entry or its own entry for that system. |
"Using MacCtrl in the combination for another platform will cause a validation error and prevent the extension from being installed." | command.cc lines 45-66 turn MacCtrl into Ctrl in the default entry when Chrome runs on macOS. | "default": "MacCtrl+Shift+Y" gets Pass on macOS and Fail on Windows, Linux and ChromeOS. |
| "may specify at most four suggested keyboard shortcuts" | commands_handler.cc lines 100-116 count commands, not entries. They count _execute_action and the other action commands, skip media keys, and do not apply with the kCommandsAccessibility permission. | Counts as the source does. It always applies the limit, because it cannot see that permission. |
"Search is an optional modifier exclusive to ChromeOS." | ui/.../command.cc lines 28-34 allow 4 parts only when Chrome runs on ChromeOS. command.cc lines 243-267 parse every entry on every system. | "chromeos": "Ctrl+Shift+Search+Y" gets Pass on ChromeOS and Fail on Windows, macOS and Linux. Search in default gets Fail everywhere. |
"Command (macOS only)", "Option (macOS only)" | command.cc lines 205-229 reject both in every entry except mac, also in default on macOS. | "default": "Command+Shift+Y" gets Fail on all four systems. |
"valid object properties are default, chromeos, linux, mac, and windows". The page does not say what happens with another key. | ui/.../command.cc lines 215-223 reject any other key. | An entry such as "ios" gets Fail on all four systems. |
"Keyboard shortcut suggestions for global commands are limited to Ctrl+Shift+[0..9]." Also: "ChromeOS does not support global commands." | The parser has no such check (command.cc line 203). command_service.cc lines 540-576 only skip assigning other global shortcuts. Media keys and the kCommandsAccessibility permission are exceptions. The fetched files have no rule about global commands on ChromeOS. | A global "suggested_key": "Ctrl+Shift+Y" gets Pass on all four systems, with a note that Chrome does not assign it. The checker does not test the ChromeOS sentence. |
"_execute_action (Manifest V3), _execute_browser_action (Manifest V2), and _execute_page_action (Manifest V2)" | commands_handler.cc lines 121-145 do not read manifest_version. They look for the action, browser_action or page_action key. Without it they add a warning and ignore the command. | Shows the warning when you paste a whole manifest. Whether Manifest V3 accepts a browser_action key is decided in a file that the checker does not cover. |
| The page does not say whether an action command can use a media key. | command.cc lines 257-259 turn off media keys for action commands. | "_execute_action": {"suggested_key": "MediaPlayPause"} gets Fail on all four systems. |
Sources
The Chromium files were fetched from the main branch on 2026-10-30, except the last three files in the list, which were fetched at the same commit on 2026-10-31. On 2026-10-30 main was commit aa08c55cb412681fb8d660739545334b4764bb69, and each file was the same as at that commit. The links point to that commit.
- Commands API reference on developer.chrome.com, fetched 2026-10-30, last updated 2026-10-29. It describes the manifest syntax, the key names and the limit of four.
- extensions/common/command.cc, fetched 2026-10-30. It parses one command: the description, the platform entries, the Command and Option rule and the macOS names.
- extensions/common/api/commands/commands_handler.cc, fetched 2026-10-30. It reads the whole
"commands"object, counts toward the limit of 4 and checks the action commands. - ui/base/accelerators/command.cc, fetched 2026-10-30. It parses one shortcut string: the platform key, the number of parts, the key names and the modifier rule.
- ui/base/accelerators/command_constants.h, fetched 2026-10-30. It lists the platform keys and the key names.
- extensions/common/manifest_constants.h, fetched 2026-10-30. It holds the error texts that the checker shows.
- chrome/browser/extensions/commands/command_service.cc, fetched 2026-10-30. It decides which suggested keys Chrome assigns: taken keys and global commands.
- extensions/common/file_util.cc, fetched 2026-10-31. Line 335 reads manifest.json with the default options of the JSON file reader.
- base/json/json_file_value_serializer.h, fetched 2026-10-31. Line 66 makes those default options
JSON_PARSE_CHROMIUM_EXTENSIONS. - base/json/json_reader.h, fetched 2026-10-31. Lines 50-84 define the options: comments, line breaks inside strings and
\xNNescapes, but not trailing commas.
Limits of this checker
This tool checks the manifest only. It does not know the shortcuts of the browser or of other extensions, and Chrome can ignore a suggested key that another extension already uses.
The commands reference page says: "Certain operating system and Chrome shortcuts (e.g. window management) always take priority over Extension command shortcuts and cannot be overridden."
What does the checker not test?
- Chrome's own shortcuts. Chrome does not assign a suggested key of a command that is not global when the key is a Chrome shortcut. The list of those shortcuts is not in the fetched files.
- Shortcuts that the user changed at
chrome://extensions/shortcuts. - The
kCommandsAccessibilitypermission that lifts the limit of 4. The fetched files do not show which manifest entry grants it. - The documentation's sentence that ChromeOS does not support global commands.
- The other keys of the manifest.
- Rare JSON cases that Chrome rejects but this checker accepts: nesting of 200 or more levels of objects and arrays, and lone surrogate escapes (such as
"\uD800").
Why can the number in commands[N] differ from Chrome?
Chromium numbers the commands in the order that it reads them. The checker numbers them in name order. The fetched files do not show the order that Chromium uses. So the number in an error, and the error that Chrome reports first when several commands fail, can differ. The result Pass or Fail for each system does not depend on the order.
Does the checker send my manifest anywhere?
No. The checker code has no network calls. It reads your text from the text field and parses it in your browser.
How does key recording work?
Turn on "Record the keys that I press" and press a combination in the shortcut field. On macOS the checker writes the Command key as Command, the Control key as MacCtrl and the Option key as Option, and checks the combination as a mac shortcut. A Ctrl in the default shortcut becomes Command on macOS. On other systems the checker does not record the Windows key or the Search key. The Tab key without Ctrl or Alt still moves the focus, and Escape turns recording off. If a combination does nothing in the field, type it instead.
Related tools
To test the match patterns of an extension manifest, use the match pattern tester. To look inside a packed extension, use the CRX viewer. To check the images of a store listing, use the Chrome Web Store image size checker. To count the bytes of a chrome.storage.sync payload, use the Chrome storage quota checker.