Chrome 154 landed MV3's lost-event fix — for the 336,360 extensions that can't use it yet
Chrome 154 shipped the async_listener_registration manifest key for MV3 service workers. Here's what landed, who it covers, and why you shouldn't switch yet.
Chrome 154 hit stable on September 22, and it carried one of the most-requested reliability fixes in Manifest V3 history: an opt-in that lets an extension's service worker tell the browser "don't dispatch events yet — I haven't finished registering my listeners."
No keynote, no banner moment. Just a manifest key and a couple of Chromium CLs. This one we did see coming, though: our signal feed caught CL 8272039 — "[Extensions] Add async_listener_registration manifest key" — on August 24. It merged to main on August 20, after the 153 branch point, which per Chrome's milestone schedule put it squarely in 154. So here's the retrospective: what actually landed, who it touches, and why you shouldn't flip the switch today.
The race every MV3 developer has hit
Manifest V3 service workers are disposable. The browser terminates them when they go idle, and any event — a message, an alarm, an install — wakes up a fresh worker. The catch: Chrome requires every event listener to be registered synchronously, in the worker's very first turn.
If your registration happens after an await — reading chrome.storage, a dynamic import(), any async setup — the browser can finish dispatching the event before your handler exists. The event is silently dropped. No error, no log, just a user wondering why the extension didn't respond. Every MV3 developer has been bitten by this at least once, and the standard defensive advice — register at the top level, defer everything else — has been documented for years.
The W3C proposal, created April 27, 2026 and sponsored by Google Chrome, formalizes the escape hatch:
- the extension declares
"background": { "async_listener_registration": true }in its manifest; - on worker startup Chrome enters a "listener registration phase" and keeps matching events queued instead of dispatching them;
- the extension calls
runtime.markListenerRegistrationComplete()when ready, queued events flush in FIFO order, and ones that don't match a registered listener are discarded; - if startup fails partway through, Chrome keeps the worker's previous routing state instead of losing events into a void.
What actually landed in 154 — and what didn't
The honest retrospective version: the manifest half landed. The CL we tracked adds parsing and validation for the background.async_listener_registration key — MV3-only, rejected if you declare it without a service-worker background, and non-boolean values are refused at validation time. It's backed by an ExtensionAsyncListenerRegistration feature flag that was disabled by default, and the commit message itself says runtime event-handling behavior arrives in follow-up changes.
So as of 154 stable, what the sources we cite actually confirm is that the key is recognized. Whether the flag is enabled in the stable build — whether the queuing behavior is live for extensions that opt in — is not something those sources confirm. Test, don't trust, if you experiment with it.
The size of the fix
Our catalog reads manifests across the Chrome, Firefox, and Edge stores. The population this opt-in targets — Manifest V3 extensions with service-worker backgrounds — numbers 336,360 extensions reaching roughly 3.77 billion monthly users. That's the ceiling of who benefits once this works and rolls out.
The set includes most of the extensions you already know: uBlock Origin Lite, AdGuard AdBlocker, Adblock Plus, Grammarly, Google Translate, Adobe Acrobat, Chrome Remote Desktop, Microsoft Single Sign-On, Claude. Basically every serious MV3 extension is a candidate, because every serious MV3 extension has listener-registration order to get right.
And 19,237 listings (~218M monthly users) in that MV3 population are already removed from stores. They'll never opt into anything. That count is the usual churn of abandoned extensions — and a reminder that platform fixes only reach extensions that are still maintained. You can browse the living ones in the catalog.
The adoption math: why this reaches your users months from now
Here's the part that tempers the good news. Even if the runtime half is live in 154 today, your audience isn't on 154 today.
Six days after the stable release, Chrome 154 doesn't yet register a measurable share of Chrome users in caniuse's StatCounter-derived usage table. Its immediate predecessors barely do: 153 sits at ~0.06% of Chrome users and 152 at ~1.9% — combined under 2%. The plurality (~37%) is on 151, with sizeable chunks still on 150 (~15%) and even 145 (~16%). And Chrome 155 is scheduled for October 6, which starts the whole rollout cycle over.
The practical read: an extension that gates behavior on async_listener_registration will run that code path for a tiny slice of its users for months. That's exactly the environment where a race-condition fix ships broken — it works on the developer's own canary-or-stable machine and silently misbehaves for the 98% who aren't there yet.
What to do now
- Don't flip the key yet. The parsing half is confirmed in 154; the behavior half was feature-flagged with follow-up CLs, per the commit we tracked. Adopting before that is a gamble.
- Keep the boring pattern as your baseline. Synchronous, top-level listener registration in the worker's first turn, async setup only after every listener is attached. It works on every Chrome version your users actually run.
- Track the proposal. When the runtime CLs land and the flag flips, the payoff is real: you can legitimately await storage or a dynamic import before declaring readiness, instead of the defensive top-level gymnastics.
- Got bitten by the wake-up race before? Note this one down and re-test your workaround later this year — don't remove the workaround today.
If you're mid-migration or auditing your manifest right now, my free Manifest V3 generator builds a cross-browser manifest with live store-policy validation, and the @extenshi/cli scanner flags MV3 background-pattern problems before you upload — 3 free scans, one-time, with prepaid packs past that.
See where your extension stands in the catalog → — 336,360 MV3 extensions are waiting on this fix. Yours is one of them.
Sources
- Chromium CL 8272039 — add the
async_listener_registrationmanifest key — Chromium code review (Google) - Chrome 154 milestone schedule — ChromiumDash (Google)
- Chrome 155 milestone schedule — ChromiumDash (Google)
- Async listener registration proposal — W3C WebExtensions Community Group
- Browser usage table — caniuse.com (StatCounter-derived)
Catalog numbers come from Extenshi's scans of each store listing's manifest_version and background configuration, plus last-observed store availability, as of September 2026; counts shift as we re-scan. Technical claims come from the cited Chromium CL, Chrome milestone schedule, and W3C proposal; Chrome version shares from caniuse.com's StatCounter-derived usage table. We don't independently verify upstream vendor claims. If you think something here is inaccurate, tell us at [email protected].
Related Articles

chrome.alarms in Manifest V3: background jobs that outlive the service worker
MV3 kills setInterval. Build a Chrome extension background job with chrome.alarms that survives service worker termination — full runnable code, ~20 min.

Offscreen documents in Chrome extensions: how to use the DOM from an MV3 service worker
MV3 service workers have no DOM. Build a Chrome extension that parses HTML and writes to the clipboard from an offscreen document — runnable code, ~25 min.

Chrome's native browser namespace: what cross-browser extension devs should do now
Chrome added a native, promise-based browser.* namespace in 148. Across the 235,887 Chrome extensions we track, here's what it changes — and what to do.

We counted what Chrome's Manifest V2 sunset actually removed — and it wasn't the ad blockers
Everyone said Chrome's Manifest V2 deadline would kill ad blockers. Here's what the sunset actually stranded — and why Firefox is now the MV2 refuge.