Extension Pulse, week of October 19: Chrome floats a brand-new API, Firefox starts throwing
Chrome proposes chrome.crossOriginStorage, a new MV3 API. Firefox 158 ships a breaking publicSuffix change, runtime.getVersion() parity and MessageSender.windowId.
New extension APIs don't appear out of nowhere very often, so when CL 8605006 landed in Chromium review on October 17, it caught my attention twice. Once for what it proposes: chrome.crossOriginStorage, a full MV3-only API to inspect and delete Cross-Origin Storage — the data sites share with each other, which DevTools currently shows one origin at a time. And once for what happened next: a companion CL to expose the same data to webRequest was created and abandoned within about 24 hours. Chrome considered letting you observe cross-origin storage through webRequest, and chose the declarative path instead.
That choice is the story, not just the API. Last week I walked through Chrome 157's slate: webRequest and DNR events going dark on user-restricted sites, a header vanishing on Gaia URLs — absence, not deprecation dialogs. This week's proposal points the same direction. When Chrome builds something new for extension visibility into cross-origin data flows, the sanctioned surface is declarativeNetRequest, not webRequest observation. The abandoned CL is the tell.
Here's what's on the table, per the CL commit message — with the big caveat that nothing has merged. Both CLs were still open/in-review as of October 21, so this is a proposal to watch, not an API to build against.
What chrome.crossOriginStorage would actually do
The pitch: "Lets extensions and automation see and manage the whole of Cross-Origin Storage, which DevTools shows one origin at a time." The surface, from the CL:
getEntries({pageSize, pageToken})returning{entries, nextPageToken}— a paged view of the whole registry, stable while entries come and go.removeEntry({algorithm, hash})— delete a specific entry by hash.- A coalesced, payload-free
onChangedevent — and a nice detail: the registry is only observed while an extension is actually listening.
Entries would carry real forensic metadata: hash, size, sniffed content type, storing origins, readers with read counts, sharing flags (sharedWithOrigins, globallyDisclosable, onPublicHashList), and creation/last-read times. If you ship a privacy cleaner, a site-data manager, or an enterprise DLP tool, that's a complete picture of who stores what and shares it with whom — instead of the heuristics you're stitching together today.
The guardrails: a new crossOriginStorage permission, MV3 only, additionally gated on Chrome's CrossOriginStorage base feature being enabled. The install prompt would read "Read and delete files that sites share with each other" — if you adopt this, plan your store listing around that wording, because it's the sentence your users will judge you by.
The companion CL 8605007 (also still in review) lets declarativeNetRequest block Cross-Origin Storage lookups by hash, and the main CL's commit message names chrome.browsingData clearing of COS as a follow-up on the same bug — a natural fit if you already surface browsingData controls in your privacy UI. There's also a DevTools protocol path (Storage.getCrossOriginStorageEntries / deleteCrossOriginStorageEntry with browserContextId) for automation on the browser target — but extensions can't ride it, because chrome.debugger doesn't attach to the browser target.
Timing: if it merges before the October 26 M158 branch point, the earliest possible ship is Chrome 158, stable November 17. M158's feature freeze already passed on October 5 and review is still open, so a later milestone is the realistic bet. Watch the CLs; don't write code yet.
Firefox 158 is live — and publicSuffix now throws
The breaking change this week didn't come from Chrome's future pipeline. It already shipped. Firefox 158 hit stable on October 13 (Mozilla product-details lists the 158.0 release on that date; 158.0.1 is current), and among the add-on changes, one bites: publicSuffix.isKnownSuffix() now throws an error on invalid hostnames instead of returning false (MDN, Firefox 158 for developers).
W42 flagged the Chrome half of this convergence — CL 8464103, merged September 30 alongside spec PR #1097, rejecting leading-dot hostnames in Chrome 157 (stable November 3). Firefox went first, and its change is broader than leading dots: any invalid hostname now raises.
The practical breakage pattern is ugly because it's loud. Code like if (!browser.publicSuffix.isKnownSuffix(x)) where x can be an empty string, a leading-dot host, an IP-literal fragment, or anything URL- or user-derived now throws instead of taking the false branch — and an uncaught exception in an event listener can abort the whole handler. Domain blockers, cookie managers, URL classifiers: exactly the tools that adopted publicSuffix early (the API itself only shipped in Firefox 153, July 21) are the ones exposed.
One fix covers both browsers: normalize and validate before calling — strip leading dots, reject empty and non-host strings — or wrap every publicSuffix call in try/catch. Test on Firefox 158 stable today; it's already live. Then confirm on Chrome 157 beta (final beta October 21) before November 3.
Two Firefox firsts: windowId lands, getVersion completes parity
Firefox 158 also added runtime.getVersion() — returning your extension's own version as declared in the manifest (WECG #878 closed April 8; Firefox's implemented: label joined Chrome's and Safari's on October 12). Small, additive, cannot break anything — but it completes three-browser availability, so the pattern behind changelog popups, version-gated migrations, and telemetry self-reporting no longer needs a hardcoded version string or a fetch(runtime.getURL('manifest.json')) self-read. Swap them in where a Firefox 158+ baseline is fine; keep the manifest-fetch fallback for older releases.
The bigger first: Firefox is now the first browser to implement runtime.MessageSender.windowId (WECG #1077). The commit — "Bug 2072133 - Add MessageSender.windowId r=robwu" (f43deb1ab6b2) — landed on mozilla-central October 16, riding the Nightly 160 train. Mozilla's release schedule puts Firefox 160 stable on November 10 (159 ships October 27). Chrome and Safari remain supportive with no public implementation CL.
The proposal (filed September 5; all three vendors marked it supportive after the September 10 WECG meeting) fixes a real gap: windowId was only reachable via sender.tab, but popups, side panels, and devtools panels don't always populate tab. Multi-window workflows — per-window state, window-specific side panels, tab-group managers — can eventually stop chaining sender.tab?.windowId fallbacks and getContexts() round-trips.
One semantics warning before you get excited. Per carlosjeurissen in #1077 (October 17): when no window id can be found or determined, Firefox leaves the whole windowId property absent — it does not use the WINDOW_ID_NONE sentinel. So feature-detect "windowId" in sender, treat undefined as "no determinable window", and don't assume Chrome's future implementation will match until the spec text pins it. Cross-browser adoption only becomes safe once a second vendor ships, and neither Chrome nor Safari has a public implementation yet.
The rest of the frame
The market clock now runs to April 2027. Chromium Dash published the first dated schedule for Chrome 167: branch point 2027-03-22, earliest beta 2027-03-24, stable 2027-04-13 (feature freeze not yet dated). That extends the 14-day cadence — M165 stable 2027-03-16, M166 2027-03-30, M167 2027-04-13 — to seven milestones between January 19 and April 13, 2027. Same advice as last week: plan migrations against branch points, not stable dates.
This week's near-term dates, re-verified in Chromium Dash on October 21: M157 unchanged — final beta October 21, stable November 3 carrying the whole W42 break list. M158 branches October 26 (the crossOriginStorage cutoff above). And Chrome 156 reached broad stable on October 20 (156.0.8078.47/.48).
Carryovers, one line each (all covered in depth in W42): alarms.clearAll() → Promise<undefined> ships with M157 on November 3; runtime.onEnabled is live in Chrome 155 and the rename to onLoaded was rejected; own-tab url/title without the tabs permission works across four browsers — drop the permission if that's all you needed; the private-DOM-classes proposal is dead unless TPAC (October 26–30, Dublin) revives it with the CSS WG.
What I'd do this week
- Harden every
publicSuffixcall today — try/catch or validate-and-normalize (strip leading dots, reject empty/non-host strings). Firefox 158 already throws; Chrome 157 rejects leading dots from November 3. One fix, both browsers. - Do the W42 M157 audit if you skipped it. Final beta lands October 21, stable November 3. Grep for
clearAllbranches, test your webRequest/DNR streams against user-restricted sites, and check any Gaia header logic. The window is two weeks, not two months. - Privacy/cleaner/DLP authors: watch CLs 8605006 and 8605007, don't build yet. If they merge before October 26, M158 (November 17) is the earliest ship. Start thinking about how "Read and delete files that sites share with each other" reads in your listing.
- If you route messages from popups, side panels, or devtools panels, keep
sender.tab?.windowId+getContexts()for now — but write the Firefox-friendly detection ("windowId" in sender,undefined= no window) so you're ready when 160 ships on November 10. - Replace hardcoded version strings with
runtime.getVersion()where your baseline allows it. - Scan your own build before you ship it.
npx @extenshi/cli scangets you 3 scans + 10 reads free with a free account (one-time); prepaid packs if the pre-M157 audit turns into a habit.
Sources
- Chromium CL 8605006 —
chrome.crossOriginStorageAPI proposal, created 2026-10-17, in review (not merged) as of 2026-10-21 - Chromium CL 8605007 — DNR blocking of Cross-Origin Storage lookups by hash, in review (not merged) as of 2026-10-21
- Chromium CL 8606266 — webRequest visibility for COS, abandoned 2026-10-18
- Chrome 158 milestone schedule — branch point 2026-10-26, stable 2026-11-17
- MDN: Firefox 158 for developers —
publicSuffix.isKnownSuffix()throws on invalid hostnames;runtime.getVersion()added; released 2026-10-13 - Mozilla product-details — Firefox 158.0 released 2026-10-13, current 158.0.1, Nightly 160.0a1 (re-fetched 2026-10-21)
- Chromium CL 8464103 —
chrome.publicSuffixleading-dot rejection, merged 2026-09-30, ships M157 (stable 2026-11-03); WECG PR #1097 spec update, merged 2026-09-30 - WECG #878 —
runtime.getVersion()proposal, closed 2026-04-08;implemented:labels for Chrome and Safari (2025-10) and Firefox (2026-10-12) - Firefox commit f43deb1ab6b2 — "Bug 2072133 - Add MessageSender.windowId r=robwu", committed 2026-10-16
- Mozilla release schedule for Firefox 160 — Firefox 159 release 2026-10-27, Firefox 160 release 2026-11-10
- WECG #1077 —
runtime.MessageSender.windowIdproposal (filed 2026-09-05);supportive:labels from all three vendors after the 2026-09-10 meeting,implemented: firefoxlabel 2026-10-17; carlosjeurissen's absent-vs-WINDOW_ID_NONEsemantics note, 2026-10-17 - Chrome 167 milestone schedule — branch point 2027-03-22, stable 2027-04-13 (fetched 2026-10-19); Chrome 166 schedule — stable 2027-03-30 (fetched 2026-10-12)
- Chromium Dash milestone schedules for M156/M157 — M156 broad stable 2026-10-20 (156.0.8078.47/.48 in the Stable channel), M157 final beta 2026-10-21, stable 2026-11-03 (re-verified 2026-10-21)
- Extension Pulse 2026-W42 — carryover coverage: M157 break list,
alarms.clearAll(),runtime.onEnabled, own-tab metadata, private-DOM-classes rejection
Methodology
Compiled from 12 Extenshi forecast-pipeline signals dated 2026-10-12 and 2026-10-19. The 2026-10-12 batch was covered in depth in W42; those signals appear here only as re-verified calendar dates and one-line carryovers. The crossOriginStorage CLs are unmerged proposals — confidence is capped accordingly, and the M158 date is the earliest possible ship, not a commitment. The Firefox 160 stable date (2026-11-10) comes from Mozilla's release schedule. CL statuses and calendar dates were re-checked on 2026-10-21, before sending.
This issue of Extension Pulse is compiled from Chromium Gerrit and Chromium Dash, W3C WebExtensions Community Group issues, Mozilla release data and MDN. We don't independently verify every upstream claim, and references to specific projects or companies reflect the findings of the cited sources — not accusations of intentional wrongdoing. If something here is off, tell us at [email protected].
Related Articles

Extension Pulse, week of October 12: Chrome 157's break list is already written
Chrome 157 beta started October 14 with five extension changes merged. Chrome 156 hits early stable. Plus runtime.onEnabled and a rejected W3C proposal.

Blocking requests in a Chrome extension: a hands-on declarativeNetRequest tutorial
Build a Manifest V3 Chrome extension that blocks trackers and strips tracking parameters with declarativeNetRequest — full runnable code, ~30 minutes.

chrome.privacy in browser extensions: build a panel that admits what it can't change
Build a Chrome privacy API panel that checks levelOfControl before changing settings. Add optional permissions and browsing-data controls with full MV3 code.