Webview service-worker cache is not invalidated when an extension updates in place: webview permanently blank, survives reboot
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Type: Bug
## Summary
When an extension updates **in place** (while VS Code is running), the webview
service-worker cache on disk keeps resolving that extension's webview assets
against the **old** extension directory — the very directory VS Code deletes on
the next start. Every asset request then fails with `net::ERR_FAILED`, the
webview's app never mounts, and the user is left with a permanently blank panel.
The cache is on disk, so this **survives a panel reload, a window reload, a VS
Code restart, and a full machine reboot**. The only cure is deleting the cache
directories while VS Code is not running.
I have reproduced this twice on two consecutive in-place updates of the same
extension, and both times the same cache deletion fixed it deterministically. I
believe this is the root cause behind a cluster of "blank webview after update"
reports across *different, unrelated* extensions (see "Not extension-specific" below).
## VS Code version
- VS Code: 1.128.0, commit `fc3def6774c76082adf699d366f31a557ce5573f`, x64
- OS: Debian GNU/Linux 12 (bookworm), kernel 6.1.0-50-amd64
- Extension used to observe it: `openai.chatgpt` (26.707.31428 → 26.707.41301 → 26.707.71524)
## Steps to reproduce
1. Run VS Code with an extension that renders its UI in a webview, and open that webview.
2. Let the extension auto-update **in place**, i.e. while VS Code keeps running.
3. Restart VS Code (or reboot).
4. Open the extension's webview → blank; only static assets that happen to still be
cached render.
I cannot make this fire on demand — it depends on the update landing while the
webview's service worker has an active on-disk resource map. But once it *has*
fired, the broken state is 100% stable across restarts, which makes the diagnosis
below easy to confirm.
## Evidence
**1. VS Code deletes the extension directory the cache still points at.**
From `~/.config/Code/logs/20260714T120150/sharedprocess.log`:
```
2026-07-14 12:01:55.024 [info] Marked extension as removed openai.chatgpt-26.707.41301-linux-x64
2026-07-14 12:01:56.557 [info] Deleted marked for removal extension from disk openai.chatgpt /home/tg/.vscode/extensions/openai.chatgpt-26.707.41301-linux-x64
```
Afterwards only the new versioned directory exists, and there is no stale entry in
`~/.vscode/extensions/.obsolete`. **Extension cleanup is working correctly** — this
is explicitly *not* an "old extension folders left behind" problem. The cache is
simply never told.
**2. The cache predates the new extension.** Directory mtimes in the broken state:
```
2026-07-14 09:45:41 ~/.vscode/extensions/openai.chatgpt-26.707.71524-linux-x64 <- new extension
2026-07-12 16:17:49 ~/.config/Code/Cache
2026-07-12 16:17:49 ~/.config/Code/CachedData
2026-07-12 16:17:49 ~/.config/Code/Code Cache
2026-07-12 16:17:49 ~/.config/Code/GPUCache
2026-07-12 16:17:52 ~/.config/Code/Service Worker <- built while the OLD version was live
```
The service-worker cache was last built while the now-deleted 26.707.41301 was the
active version.
**3. The failure is confined to the webview — every log you would normally check is green.**
The extension host activates the extension, its backend starts and completes its
handshake, and neither `renderer.log` nor `exthost.log` contains a single error:
```
2026-07-14 12:01:54.428 [info] Activating Codex extension
2026-07-14 12:01:54.428 [info] [CodexMcpConnection] Spawning codex app-server
2026-07-14 12:01:56.106 [info] [CodexMcpConnection] Initialize received id=1
```
This is, I suspect, why this bug has been so hard to pin down: nothing surfaces
anywhere except inside the webview itself.
**4. The actual error, from *Developer: Open Webview Developer Tools* → Console:**
```
Failed to load resource: net::ERR_FAILED .../webview/assets/.js
```
…for chunks that **demonstrably exist on disk** under the *new* extension path. The
service worker is resolving them against the old, deleted path, so the app never
mounts.
*Full disclosure:* this console capture is from the first occurrence (2026-07-12).
On the second occurrence (2026-07-14) I went straight to the fix and did not
re-open the DevTools console; all other evidence in this report is from 2026-07-14.
## Workaround (not a fix)
With VS Code **shut down**:
```bash
rm -rf ~/.config/Code/{"Service Worker",Cache,"Code Cache",GPUCache,CachedData}
```
Pure caches — settings, extensions and user data are untouched, and VS Code rebuilds
them on the next start. 2 / 2 successful. Notably, *nothing short of this works*:
not reloading the webview, not `Developer: Reload Window`, not restarting VS Code,
not rebooting the machine.
## Expected behaviour
When the extension directory backing a webview's cached resource map is removed (or
the extension's version changes), VS Code should invalidate the corresponding
service-worker cache entries — or, at minimum, key them by extension version so a
stale entry cannot shadow a valid new one. Right now a routine auto-update can leave
an extension permanently unusable in a way the user has essentially no chance of
diagnosing.
## Not extension-specific
The same failure has been reported against unrelated extensions, which is what makes
me think this belongs here rather than in any one extension's tracker:
- `anthropics/claude-code#13130` — webview goes blank after auto-update, stale resource
references into the old extension folder (`ERR_FILE_NOT_FOUND` on the old path).
Closed as *not planned*, unresolved.
- `openai/codex#32388` — **still open**; Linux, VS Code **1.128.0**, extension version
**26.707.41301** — i.e. the exact VS Code and extension version I saw this on. Same
symptom, no root cause found; the reporter's accidental workaround is starting VS Code
with `--disable-extension `.
- `openai/codex#15975`, `openai/codex#28280` — still open, same symptom, no root cause found.
The closest existing issues here (#78542 extension *code* cache, #192965 webviews
failing after 1.82) are both closed and describe different mechanisms, so I am filing
this as a new report rather than commenting on them. Happy to gather more data if you
can tell me what would help — in particular I did not keep a copy of the broken
`Service Worker` directory, and I can do that next time it fires.
Contributor guide
Assessment
This issue has not been assessed yet.