[Bug] MSIX stealth update relaunch fails with 0x80070020, app becomes unlaunchable
Bug Description
Title: [Windows/MSIX] Stealth auto-update relaunch fails permanently with 0x80070020 — app becomes unlaunchable, shell reports "Claude is already in use"
Summary
The desktop app's idle-triggered "stealth update" quits the app to relaunch itself, but the
relaunch fails at the MSIX layer with 0x80070020 (ERROR_SHARING_VIOLATION). The failure is
permanent, not transient — every subsequent launch attempt fails identically. Windows
surfaces this to the user as "Claude is already in use", which is misleading: no Claude
process is running at all.
Environment
- Windows 11 Pro, build 26200.9168
- Claude desktop: package
Claude_1.37937.1.0_x64__pzs8sxrjxfjjc(MSIX/Store), version 1.37937.1.0 - Claude Code CLI: 2.1.246 (installed separately at
~/.local/bin/claude.exe, unaffected) - Machine uptime at time of failure: ~7 days
Get-AppxPackage Claude*reportsStatus: Ok, version 1.37937.1.0 — i.e. the package is
intact and the staged update did apply. Only process launch is broken.
Timeline / evidence
%LOCALAPPDATA%\Claude\logs\main.log — the app decides to update and quits:
2026-08-26 17:23:29 [info] [stealth-update] Triggering stealth update after idle timeout
2026-08-26 17:23:29 [info] [stealth-relaunch] Saved z-order anchor: 0xb240fa0 (above our 0x508d0)
2026-08-26 17:23:29 [info] [stealth-relaunch] Saved navigation history (50 entries, active=49)
2026-08-26 17:23:29 [info] [popout-restore] Saving 0 session popout(s) for next launch
2026-08-26 17:23:29 [info] beforeQuitForUpdate handler fired, going down for update
2026-08-26 17:23:29 [info] Windows session ending (close-app) - quitting the app
main.log ends here. Nothing is ever appended again — the relaunched process never reaches
Electron main.
Event log Microsoft-Windows-AppModel-Runtime/Admin, two seconds later:
17:23:31 Id 215 0x80070020: Cannot create the Desktop AppX container for package
Claude_1.37937.1.0_x64__pzs8sxrjxfjjc because an error was encountered
converting the job.
17:23:31 Id 215 (same, repeated)
17:23:31 Id 208 0x80070020: Cannot create the process for package
Claude_1.37937.1.0_x64__pzs8sxrjxfjjc because an error was encountered
while configuring runtime. [LaunchProcess]
These 17:23:31 entries are the earliest Claude-related errors in the retained event log —
the app had been running normally all day until the stealth update. The identical triple then
repeats on every manual launch attempt afterward:
18:05:23, 18:05:48, 21:15:49, 21:15:50 — same Id 215 / 215 / 208, same 0x80070020
At 21:15:49 the container lifecycle partially succeeds before failing, suggesting a race
rather than a plain file lock:
Id 211 Added process 84768 to Desktop AppX container 33ccc0aa-... for package Claude_...
Id 219 PSMFlags for Desktop AppX process ...
Id 217 Destroyed Desktop AppX container {33CCC0AE-...} for package Claude_...
Id 215 0x80070020 ... converting the job
Id 208 0x80070020 ... [LaunchProcess]
Verification that nothing is actually in use
Get-Process | Where-Object { $_.Path -like 'WindowsAppsClaude' -or $_.Path -like 'Packages\Claude*' }
-> no results
No packaged Claude process, no leftover Electron renderer/gpu/utility children. The
"already in use" message is Windows misreporting ERROR_SHARING_VIOLATION from the failed
AppX container/job-silo creation, not a live instance.
Expected vs actual
- Expected:
beforeQuitForUpdate→ process exits → new version relaunches → window restores
(z-order anchor and 50-entry nav history were saved specifically for this).
- Actual: process exits, relaunch fails, app is unlaunchable indefinitely. The saved window
state is never restored. No error is shown to the user at quit time — the app just vanishes
and only fails visibly on the next manual launch, hours later.
Impact
Silent, self-inflicted, and permanent until the user reboots or re-registers the package.
Because the failure is invisible at quit time, the user's mental model is "the app crashed",
and the shell's "already in use" message actively points diagnosis in the wrong direction
(hunting for a phantom running instance). Diagnosing this required digging through the
Windows AppModel event log — not a reasonable ask.
Workarounds found
- Re-register the package (no data loss, no reboot):
Get-AppxPackage Claude* | ForEach-Object {
Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"
}
- Reboot — clears the stale container/job state.
Suggested fixes
- Don't tear down the old process until the new one is confirmed launched; ve…
Note: Content was truncated.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
WA (get-appxPackage) proposed doesn't work.
You're right — a reboot isn't a workaround, it's an admission that the app puts itself into a state nothing short of destroying the logon session can recover. That belongs in the report as a severity point, not a fix. Here's the follow-up:
Update — original report was wrong about the workaround, and the root cause is narrower than I described
Correction: re-registering the package does NOT fix this
Workaround #1 in my report (
Add-AppxPackage -Register) is wrong. Please disregard it.It completes successfully and the app still fails to launch ~200ms later:
21:26:12 Deployment Register operation on Package Claude_1.37937.1.0_x64__pzs8sxrjxfjjc
from: (AppxManifest.xml) finistime: 703 ms
21:26:12 Successfully updated the status for package Claude_1.37937.1.0_x64__pzs8sxrjxfjjc
21:26:12 0x80070020: Cannot create the process for package Claude_... [LaunchProcess]
The package was never corrupt. `Get-AppxPackore and after.
Sharper root cause: the FIRST container succeeds, subsequent ones fail
Full event sequence from a single launch attempt (
Microsoft-Windows-AppModel-Runtime/Admin):21:26:12 Id 210 Created Desktop AppX container {33CCC860-...} for package Claude_1.37937.1.0_x64__pzs8sxrjxfjjc
21:26:12 Id 211 Added process 16724 to Desktop AppX container 33ccc860-... for package Claude_...
21:26:12 Id 219 PSMFlags for Desktop AppX process ...
21:26:12 Id 217 Destroyed Desktop AppX container {33CCC864-...} for package Claude_...
21:26:12 Id 215 0x80070020: Cannot create the Desktop AppX container ... error encountered converting the job.
21:26:12 Id 217 Destroyed Desktop AppX container {33CCC865-...} for package Claude_...
21:26:12 Id 215 0x80070020: Cannot crer ... error encountered converting the job.
21:26:12 Id 208 0x80070020: Cannot create the process for package Claude_... [LaunchProcess]
The Electron main process gets into a container fine. The child processes
(renderer / GPU / utility) then fail to be pith
0x80070020 ... converting the job, and the app dies before reaching Electron main.Confirming it never reaches main:
%LOCALAPPDATA%\Claude\logs\main.loghas a last-writetime of 17:23 and has not grown by a single byte across 9 subsequent failed launch
attempts (17:23:31, 18:05:23, 18:05:24, 18:05:48, 18:05:49, 21:15:49, 21:15:50,
21:26:12, 21:26:12). There is no app-side log of any of these failures — the only record
anywhere on the system is the Windows event log.
Ruled out by evidence
*WindowsApps*Claude*or*Packages\Claude*exists.Microsoft.ScreenSketchat 21:26:14,Microsoft.DesktopAppInstallerat 21:26:13.Both are single-process; Claude is the multi-process one. This is specific to spawning
children into the package container.
Windows Defender only. Docker Desktop and WSL are running but are not in this code path.
What remains is stale kernel-side container/silo state for this package, created when the
17:23 stealth-relaunch raced its own shutdown. Package-level operations can't touch it —
it's bound to the logon session.
"Reboot" is not a workaround — it's the severity
The only things that clear this are signinoting, because
Desktop AppX containers are per-logon-session. That is not a workaround; that is the app
having no recovery path short of destroying the user's entire session. On this machine that
means killing Docker containers, a Unity editor, and running CLI sessions — to recover a
chat client that broke itself while idle.
Restating the severity in those terms:
permanently unlaunchable.
is actively misleading: nothing is in use.
0x80070020isERROR_SHARING_VIOLATIONandthe shell renders it as an in-use message. hunt for a
running instance that does not exist.
Microsoft-Windows-AppModel-Runtime/Adminin Event Viewer todiscover that the answer is "log out." No ordinary user reaches that conclusion.
current (latest: 1.37937.1, lastTarget: 1.37937.1)` on a 20-minute loop for hours
beforehand. The version did not change. Itwhat it already had.
Requested fixes (revised)
the old process; if
LaunchProcessfails, abort the update and keep the window.teardown had no update to apply.
0x80070020with backoff on container creation instead of exiting into a statethat survives every launch attempt afterw
main.logending silently mid-line is the reason this took an event-log dig0x80070020, say what'sactually wrong and what clears it — not the OS's "already in use" text.
Fresh reproduction on 2.110.1 — still live three weeks and a major version later
Same failure as this report, on a different machine, on a much newer build. Posting because this
issue is currently labelled
invalidand because my data refines two of the claims here ratherthan just repeating them.
Environment
| | |
|---|---|
| OS | Windows 11 Pro 10.0.26200 |
| Package |
Claude_2.110.1.0_x64__pzs8sxrjxfjjc→Claude_2.2553.0.0_x64__pzs8sxrjxfjjc||
SignatureKind|Developer— sideloaded MSIX from the .exe download, not Store-delivered || Bundled Claude Code | 2.1.271 → 2.1.274 |
| Node | 24.20.0 |
Note the package origin: this reproduces on a sideloaded MSIX, so it is not specific to Store
delivery. (Original report lists MSIX/Store.)
Timeline —
%LOCALAPPDATA%\Claude\Logs\main.logMicrosoft-Windows-AppModel-Runtime/Admin— identical signature to this issue, on manual launchattempts:
Same
Id 215/Id 208, same0x80070020, same "an error was encountered converting the job" —i.e. the orphaned job object / silo described in #53247.
Refinement 1 — it is not necessarily permanent, and a reboot clears it
This report says *"The failure is permanent, not transient — every subsequent launch attempt
fails identically."* On this machine it was not permanent: two launch attempts failed, a reboot
cleared it, and the app started normally. Worth capturing because it changes the recovery advice and
suggests a process-lifetime-scoped resource rather than persistent on-disk state.
Refinement 2 — the same mechanism succeeded on the same machine 67 minutes later
Two seconds, clean. Same box, same code path, ~720× the downtime of the failed one. This supports
the race-condition reading in this issue over a plain file lock.
New signal — recurring
EBUSYon a file inside the app's own package directoryPresent on this machine across multiple versions, including well before the failed update:
EBUSYand0x80070020are both sharing violations. Something in the app holds open handles intoits own
WindowsAppspackage directory during normal operation. Offered as a lead: if a handle intothe outgoing package survives
beforeQuitForUpdate, that is a plausible mechanism for the job/siloconversion to fail on the way back up. Not a diagnosis — I cannot see which handle.
Impact not yet captured here — active sessions are killed, not just window state
The updater terminates live Claude Code PTY process trees. This issue notes the saved z-order and
navigation history never being restored; the sharper cost is that an in-progress Claude Code session
is killed by the updater, so a failed relaunch can mean lost work, not just a lost window.
In this instance it landed mid-working-hours and cost ~30 minutes to diagnose and reboot.
Request: make the auto-update opt-out reachable by users
A setting already exists — the app defines
disableAutoUpdates("Block auto-updates … Stop ClaudeDesktop from fetching updates entirely"), alongside
autoUpdaterEnforcementHours(1–72). Both arescoped to admin/MDM managed settings, i.e. they require a machine-wide policy file or registry key.
For an individual user on their own machine, the workaround for an updater that can render the app
unlaunchable is currently "author a Windows policy." Please surface
disableAutoUpdatesin theapp's own Settings. Until the relaunch path is reliable, the people it breaks should be able to
turn it off without administering a fleet.
Two smaller asks in the same area:
being killed to make way for an update.
surface something. A feature deliberately engineered to be invisible (
stealth-update, savedz-order, saved nav history) has no way to tell the user it failed — from the user's side the
application simply ceases to exist, with no dialog, no tray icon and no log line.
Related: #53247 (orphaned Silo / Job Object, same
0x80070020and sameId 215/208pair).Happy to supply the full
main.logor the raw event-log export if useful.