Rehoboth Builds

suggested_key is a suggestion: commands.getAll() can hand you an empty shortcut

You declare Alt+Shift+R in the manifest, the extension loads without complaint, and the key does nothing. Nothing is broken. The shortcut was simply never assigned, and the only place that says so is a field you probably never read.

8 September 2026 · measured on a shipped extension, 6 September 2026

1. What we actually saw

The manifest declares one command with a suggested_key of Alt+Shift+R. On a freshly loaded profile we asked the browser what it had done with it:

chrome.commands.getAll()
// [{ name: "read-toggle", description: "…", shortcut: "" }, …]

The command exists. Its shortcut is the empty string. There was no exception, no console warning and no entry anywhere in the extension's own logs. The word in the manifest key is suggested, and the browser is within its rights to decline.

2. The failure is invisible from inside the extension

chrome.commands.onCommand is an event. When the key is unassigned, the event never fires — which is byte-for-byte what a user who has not pressed the key looks like. There is no callback, no error, and no state to inspect after the fact. If your only evidence is "our shortcut handler is not running," you cannot tell the two apart, and both readings suggest completely different fixes.

The one field that distinguishes them is the shortcut string above, and it is only true at the moment you ask: the user can assign or clear the key at any time, so a value you read at install and cached is a value that can quietly go stale.

3. Your interface is the thing that lies

The real damage is not the missing key — a toolbar button still works. It is that the shortcut has usually been copied by hand into three places that no longer agree with the browser: the popup, the options page and the store listing. Each of them states Alt+Shift+R as a fact, because at the time somebody wrote them it was a fact in the manifest.

So the user reads a specific key combination in your own words, presses it, gets nothing, and concludes the extension is broken. That is a worse outcome than shipping no shortcut at all, and it is entirely self-inflicted: we told them something that the browser had already declined to do.

The fix is to stop printing the manifest. Read getAll() when you render the surface, print the string that comes back, and when it is empty say so in the same breath as where to fix it. For text you cannot generate at runtime — a store listing is written once and read by strangers — the honest form is conditional: name the default and say the browser does not always assign it.

4. You cannot assign it for them

There is no API that binds a shortcut. Assigning one is a user action on the browser's own shortcuts page, and a page on the open web cannot link to a chrome:// URL — the browser blocks the navigation — so instructions that live on your website have to be something the reader can type or paste, not something they can click.

Which makes this a copy problem rather than a code problem, and copy problems do not surface in tests. It is worth saying plainly in the one place a confused user actually looks: the key may not be assigned, here is where to assign it.

How we know

This is one measurement, not a rule we derived: we loaded the extension, called chrome.commands.getAll() from its own service worker, and read back an empty shortcut for a command whose manifest asks for Alt+Shift+R. We are deliberately not telling you when the browser declines — how many commands can hold keys, or which combinations are taken — because we did not measure that, and a confident rule with no measurement behind it is the thing that put the wrong key in our own interface in the first place. What we changed on the evidence we have is our wording: the listing on the store today names the default and then says the browser does not always assign it.

Where this came from

It came out of Highlight Reader, a Chrome extension that reads a page aloud and highlights each sentence as it speaks. It is free on the Chrome Web Store, needs no account, and uses the voices the browser already ships. A paid add-on — word-level highlighting and higher-quality voices — is described here, and it is an add-on, not the extension.

The API and the code are the easy half. The half that costs days is the store: the slot cap on a new account, the listing text going read-only mid-review, the uninstall URL you cannot change after you ship. The ten that caught us — three of them in full, no signup.