Windows desktop: stealth update leaves orphaned processes holding old AppX container; new version unlaunchable (0x80070020) until reboot
## Summary
The Windows desktop app's stealth auto-update leaves orphaned child processes that keep the OLD version's Desktop AppX container alive. Every launch of the NEW version then fails with 0x80070020 ("error encountered converting the job") until the machine is rebooted. The app appears simply dead to the user: clicking the icon does nothing.
This machine has hit the "update leaves Claude unlaunchable until reboot" state repeatedly across multiple update cycles (an earlier episode instead showed a "Another program is currently using this file" installer dialog while popped-out session processes were still running).
Environment
- Windows 11 Home 10.0.26200
- Claude desktop app (MSIX, package family
Claude_pzs8sxrjxfjjc) updating 1.34493.1.0 -> 1.37937.0.0 - Multiple Claude Code sessions / popout panes typically open at update time
Timeline (from Windows event logs, 2026-08-25, all times local)
- 13:37 - AppXDeploymentServer: Add operation for 1.37937 with
DeferRegistrationWhenPackagesAreInUse; event 658 "Marking package for deferred registration because Claude_1.34493.1.0 is still running". Normal. - 19:57:18 -
RegisterByPackageFamilyNamewithForceApplicationShutdownOption. Old version's container destroyed, registration finished successfully at 19:57:51 (event 400). - 19:57:51 onward - every relaunch of the new version logs (AppModel-Runtime/Admin):
- event 211 "Added process <pid> to Desktop AppX container ..." (main process starts)
- then repeated event 215
0x80070020: Cannot create the Desktop AppX container for package Claude_1.37937.0.0 because an error was encountered converting the job. - then event 208
0x80070020: Cannot create the process ... error encountered while configuring runtime. [LaunchProcess]
The app dies silently. This repeats identically at 20:01:31, 20:01:32, 20:01:51, 20:02:11, 20:02:38 (including two automatic re-register/repair passes, both of which "finished successfully" per event 400 yet launches kept failing).
- At this point no process named claude.exe existed (verified by an external kill script that logged
taskkill /IM claude.exe-> "process not found"). Something else - an orphaned child (conhost/node/shell) without package identity - was evidently still a member of the old container's job: at 20:03:02, during shutdown, the system logged event 217 destroying a Desktop AppX container for the old package 1.34493.1.0 that had been alive the whole time. - Reboot at 20:03:22; first launch at 20:03:47 succeeded instantly.
Analysis
beforeQuitForUpdate/ stealth update takes down the main app, but child processes spawned by Claude Code sessions (shells, MCP servers, console hosts) can outlive it. They hold membership in the old version's AppX container job.- The new version's container creation then fails at job conversion with
0x80070020until that job is gone. Since these survivors have no package identity and are not named claude.exe, neither Task Manager's "Claude" group nortasklist /appssurfaces them; a reboot is the only user-discoverable cure. - Suggested fix: before (or after)
quitForUpdate, enumerate and terminate all processes in the app's own container/job (the app owns the job handle, so it can do this reliably), or make the post-update launcher detect0x80070020and clean up the stale container instead of dying silently.
Repro conditions
Not 100% deterministic, but has occurred repeatedly on this machine: several Claude Code sessions with popout panes + background child processes open, stealth update fires after idle timeout, swap succeeds, relaunch fails until reboot.
20 Comments
Corroborating forensics from a second machine — same package family, same 1.34493.1.0 → 1.37937.0.0 transition — plus two findings that may help whoever fixes this:
Environment: Windows 11 Pro 10.0.26200,
Claude_pzs8sxrjxfjjc, multiple Claude Code sessions open at update time.Timeline (local time, from event logs):
Claude(CoworkVMService) start type changed auto→disabled; 7045: service (re)installed from theClaude_1.37937.0.0path.0x80070020: Cannot create the Desktop AppX container for package Claude_1.37937.0.0 … an error was encountered converting the job.App icon dead from here on ("Another program is currently using this file" dialog).DeferRegistrationWhenPackagesAreInUse(event 658: "deferred registration because 1.37937.0.0 is still running") — the same trap is armed for the next quit/relaunch.(Correction: the first version of this comment claimed recovery happened without a reboot. That was wrong — the boot record shows a user-initiated restart at 00:40, which is what cleared the lock.)
Finding 1 — the packaged service is stoppable by any authenticated user; a mitigation path exists today.
sc sdshow CoworkVMServicereturns:The first ACE grants Authenticated Users RP (start) and WP (stop); the DACL only reserves delete/reconfigure for the service SID. So the updater — or the app itself at quit time, unelevated — could stop
CoworkVMService(and reap any surviving processes of the outgoing package version, e.g.chrome-native-host.exeor elevated Claude Code children — cf. #84792, #73107, #53247) before completing deferred registration and relaunching. Reports that "admin can't touch the service" concern delete/config, not stop. Whether a service stop alone releases the pinned container job (vs. also needing the orphan reap) is untested on this machine — #80286 suggests stop alone may not suffice once the silo is wedged.Finding 2 — the manifest declares the service with a named-pipe trigger,
windows.service+localSystemServices/packagedServicescapabilities and<desktop6:DataItem Value="\pipe\cowork-vm-service" />, so the service can be demand-started after the swap; keeping it alive across the package transition is what pins the old container job and producesERROR_SHARING_VIOLATIONat container-job conversion.Cross-refs with the same signature: #89687, #84435, #80286, #73694. This has been reported since March/April (#45489, #47877, #36466, #48003) — all four were auto-closed by the dedupe bot and locked while the defect stayed alive; please keep this one open.
Field update — the obvious mitigation does NOT work. Stopping CoworkVMService + killing package processes at failure time was tried automatically 4× during a real occurrence today and the launch kept failing; only a reboot recovered.
Since my earlier comment I had installed an automated mitigation on this machine: a scheduled task triggered by AppModel-Runtime event 215 that (a) kills any process still running from an old
WindowsApps\Claude_*directory and (b) stopsCoworkVMService(permitted to Authenticated Users by the service DACL, per my earlier comment). Today it met a real occurrence:0x80070020"error … converting the job" forClaude_1.37937.2.0.WindowsApps\Claude_*directory at failure time, andStop-Service CoworkVMServicesucceeded on every run — yet the very next launch failed identically. (An external agent attempting manual recovery in parallel also failed.)So at failure time, whatever pins the old container job is not a visible package-path process, and it is not (only) the running service — stopping the service demonstrably does not release the wedged job/silo. This kills the simplest in-app fix ("stop the service before registering") as a complete solution, though it may still be necessary.
Post-recovery baseline on this machine: the Cowork VM runs as
vmmem+vmwp— Host Compute System processes living outside the package directory, invisible to any package-path-based cleanup, and not children of the app. Whether that compute system survives app quit and is what pins the container silo is the open question — it would be consistent with the HCS shutdown failures reported in #83494. I have instrumented the next occurrence: on event 215 the machine now captures a full inventory (package processes,claude/cowork-svc/chrome-native-host/vmmem/vmwpprocess list,hcsdiag listunder an elevated task, service state) before attempting anything. I will post that forensic snapshot when the bug next fires.For the fix: whatever quit-time/update-time path Anthropic implements, it apparently must also tear down the Cowork HCS compute system (and verify the container silo is actually gone), not merely stop
CoworkVMService.Independent reproduction of the same failure signature, adding one data point this thread doesn't have yet: an external recovery script that killed every process named
claude, deleted the Electron singleton lockfiles, and restartedCoworkVMServicedid not recover the app — only a full reboot did (both occurrences).Environment
Claude_pzs8sxrjxfjjc, updating 1.37937.2.0 → 1.37937.3.0Timeline (2026-08-27, local time)
[stealth-update] Triggering stealth update after idle timeout→beforeQuitForUpdate handler fired, going down for update→ log ends and never resumes0x80070020: Cannot create the Desktop AppX container for package Claude_1.37937.3.0_x64__pzs8sxrjxfjjc because an error was encountered converting the job.followed by event 208 ([LaunchProcess]fails with the same code)0x80070020pair and no app process ever appearsWhat did not recover it (run between the manual launch attempts):
Stop-Process -Forceon every process namedclaude(both theWindowsAppspath and the bundled claude-code path)%APPDATA%\Claude\lockfileand the LocalCache copyCoworkVMService(elevated)No crash dumps (Crashpad
reportsempty) and no Application-log errors from the app itself — the new version simply never gets a process off the ground. This is consistent with the orphaned-job analysis in the OP and with the helper-process root-cause trace in #89648: whatever survives isn't namedclaude, so name-based kills don't clear the old container's job.Prior occurrence on the same machine: 2026-08-21, updating 1.34493.0.0 → 1.34493.1.0 — main.log ends at 15:28:26 with the same
beforeQuitForUpdatesequence; 4 manual launches over the following ~3 hours all no-op'd (same repeated-Register pattern in AppXDeploymentServer); recovered by the machine's scheduled 05:00 reboot the next morning.Happy to pull more log detail from this machine if useful.
Forensic snapshot captured during a live occurrence, as promised — the pinner is identified: an orphaned
chrome-native-host.exefrom the previous container epoch, living in the package's AppData profile (not the install dir). Sign-out cured it without a reboot. The Cowork-VM hypothesis is dead:hcsdiag listwas EMPTY during the failure.Timeline 2026-08-28 (local, Windows 11 Pro 26200, same machine as my comments above):
0x80070020"error … converting the job" for 1.40609.0.0.cowork-svc.exefreshly spawned by the launch attempt itself. It was killed andCoworkVMServicestopped successfully — did not cure.hcsdiag list(elevated): empty — no Host Compute System VMs existed, ruling out the Cowork VM as the pinner.chrome-native-host.exePID 26392, running since 2026-08-26 17:26:41 — two days and two version transitions old — at%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\ChromeNativeHost\chrome-native-host.exe. It lives in the package data profile, outsideWindowsApps, so package-dir-based cleanup (mine, and apparently the updater's) never touches it.chrome-native-host.exespawns ~6 s after the app starts — consistent with an app-managed helper that is never reaped on quit/update.Conclusion (matches #84792 and #73107): the app leaves
chrome-native-host.exerunning after quit; as a leftover member of the old version's AppX container job/silo it blocks the new container's job conversion withERROR_SHARING_VIOLATIONuntil it dies. Sign-out kills session processes — hence the cure; reboot was never actually necessary.Suggested fix: the quit/update path must terminate ChromeNativeHost (and any other helpers running from the package data profile) before completing registration, and verify the old container job is actually gone before relaunching.
My local mitigation now also reaps package-profile processes on event 215; I will report whether that makes the second click succeed without sign-out at the next occurrence.
Recurred 2026-08-28, updating 1.37937.3.0 -> 1.40609.0.0 — with new evidence that the container-keeper is not any obvious process.
Same signature: after the update swap, every launch of the new version failed with event 215/208
0x80070020 ... error encountered converting the job(AppModel-Runtime/Admin, 20:20:46–20:21:13), and at shutdown (20:21:49) Windows logged destroying a Desktop AppX container belonging to the old version 1.37937.3.0 that had been alive throughout. Reboot at 20:22 fixed it; first post-boot launch succeeded instantly.New data point: this time an external cleanup script swept aggressively between launch attempts and the failure still persisted. The sweep force-killed (a) all
claude.exe, (b) every process whose command line references the package/appdata paths (caught acmd.exeand achrome-native-host.exe), and (c) verified viaGetPackageFullNamethat zero remaining processes carried Claude package identity. Launches still failed with 0x80070020 afterwards.So the old container's job is being kept alive by something with a generic name, a generic command line, and either no queryable package identity or protection from user-level OpenProcess — plausibly a
RuntimeBroker/dllhost/backgroundTaskHostinstance or a leaked kernel job handle. From the user side this is effectively undiagnosable and unkillable; reboot is the only recovery.This strengthens the case that the fix needs to live in the app/updater: terminate all members of the app's own container job on
quitForUpdate(the app owns the job handle), or have the post-update launcher detect 0x80070020 and tear down the stale container rather than dying silently — the user just sees a dead icon.Kernel-level mechanism confirmed + an in-place recovery that needs neither reboot nor sign-out — verified while the pinning process was still alive.
Environment: Windows 11 x64 10.0.26200,
Claude_pzs8sxrjxfjjc1.37937.1.0 → 1.37937.3.0. Update staged 08-27 05:00 (deferred registration, app running), force-registered 05:10; every launch for the next two days died with AppModel-Runtime 215/2080x80070020, including after twoRegisterByPackageFullName … RepairAppRegistrationOptionpasses that each "finished successfully".What exactly stays pinned: the package's Helium registry hives, still mounted in the dead container's silo
What "error encountered converting the job" actually trips on (open question in this thread): during the failure, the package's virtual-registry hive files are exclusively locked:
%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\SystemAppData\Helium\User.dat%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\SystemAppData\Helium\UserClasses.datRestart Manager names the holders as
System(PID 4) andRegistry(PID 468) — no user-mode process holds file handles. The hives are still loaded in the kernel registry, mounted under the OLD container epoch's silo.HKLM\SYSTEM\CurrentControlSet\Control\hivelistshows it directly:Launching the new version = creating a new container = mounting those same hive files →
ERROR_SHARING_VIOLATION→ the "Another program is currently using this file" box (the dialog shows the current Claude.exe path only because the error surfaces from container setup — the exe itself opens fine with any sharing mode during the failure).Consistent with the forensic snapshot above, the only surviving pre-update-epoch process on my machine was an orphaned
chrome-native-host.exe(plus itscmd.exepipe wrapper), spawned by Chrome three days before the update from%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\ChromeNativeHost\. Two details that explain why kill-script mitigations reported here didn't work:WindowsApps\Claude_*path misses it;handle64 -aon the silo name finds nothing; only its own CWD) — it pins the silo purely by job/silo membership, so handle-hunting also misses it.In-place recovery (no reboot, no sign-out), verified live
With
SeRestorePrivilegeenabled,NtUnloadKey2(…, REG_FORCE_UNLOAD)on the stale Claude entries inhivelistreleases the hive files instantly; the next launch built a fresh container and the app started normally. Notably, I did not kill the pinningchrome-native-host.exe— it is still running now, harmlessly, next to the working app. So this recovery works even when the silo member can't be found at all.Unload results for the five stale mounts:
i.e. only the
user_sid/user_classes/software/commounts of the dead silo actually block container creation.PoC (elevated PowerShell):
One more corroborating detail: stopping
CoworkVMServicedoes not release these hives (matches the field reports above) — and every launch attempt and every Repair pass reinstalls and restarts it (paired SCM 7045/7040 events each time, new PID each time), which is part of why "Repair" never helps.Fix-wise this supports what's already been suggested: before registering the staged package, the updater should tear down all members of the package's container silo(s) — explicitly including Chrome-owned native-messaging hosts under
LocalCache\Roaming\Claude\ChromeNativeHost— or, failing that, force-unload the package's stale\REGISTRY\WC\Silo*mounts exactly as above instead of leaving the user to reboot.Resolved on this machine today, and the fix has a step this thread hasn't mentioned yet: the app's MSIX StartupTask has to be disabled before you sign out. That single detail may explain why sign-out works for some people here and not others.
Environment: Windows 11 Pro 10.0.26200,
Claude_pzs8sxrjxfjjc, 1.40609.0.0 → 1.40609.1.0.The recipe that worked
Get-AppxPackage -Name Claude.Before:
1.40609.0.0, silos5d197b85-…-2758801b3aa2and7b931dd7-…-8459c8546278.After:
1.40609.1.0, siloscaa4db34-…-cd17292fd206and24e5121f-…-a008715a133a. Both old silos gone.Why step 1 matters
ClaudeStartupships asStartupTaskState = 2(Enabled). If you sign out with it enabled, the app relaunches during logon, a fresh silo is created, and the pending registration is deferred again. From the outside this looks exactly like "signing out didn't help" — which is what I'd have reported had I not checked the registry key first.Two measurements that narrow the root cause
1.
Add-AppxPackage -Registerfails with zero package processes alive. With the app closed andCoworkVMServicestopped, I verified no process had an image path underWindowsApps\Claude_*orPackages\Claude_pzs8sxrjxfjjc\*, then ran:Windows asked me to close an app that had no processes. An exclusive-open test on the package hives right after reported both as locked:
SystemAppData\Helium\User.datandUserClasses.dat. This is direct evidence that the blocker is the mounted hive, not a surviving process — which is also why every process-killing mitigation in this thread, including three of my own, never worked.2.
NtUnloadKey2returnsSTATUS_ACCESS_DENIEDwhile the silo is live. Following @bugale's PoC above, elevated, withSeRestorePrivilegeenabled andREG_FORCE_UNLOAD, all five Claude mounts returned0xC0000022:The hives stayed locked. I believe the difference from @bugale's
STATUS_SUCCESSis silo state: their unload ran against a dead silo after a failed launch, mine against a live one that had never been torn down (same silo id since at least 15:18 that day, across several app closes). If that holds, the in-place recovery works only after the container is already wedged, and cannot be used preemptively.Deferred registration is never retried inside a live session
The update request originates from the app itself (event 854, fetching from
downloads.claude.ai). Windows refuses because the app is running (event 638,Running apps: {Claude_pzs8sxrjxfjjc!Claude}) and marks it deferred (event 658). With the app closed from 16:27 to 16:39,AppXDeploymentServer/Operationallogged no deployment events at all for the package. Nothing retries. The request only exists while the app runs; the registration can only complete while it doesn't.Suggested fix
Before registering a staged package, tear down the outgoing container's silo, and don't rely on process enumeration to decide it is safe — the blocking resource is the mounted hive set, which outlives every process. Failing that, the updater could retry the deferred registration on app exit instead of leaving it for a logon that may never happen without one.
Also worth considering: shipping
ClaudeStartupenabled by default actively defeats the sign-out workaround that this thread currently recommends.Happy to run further diagnostics on request; the machine is instrumented for this now.
Third-party confirmation of @bugale's hive analysis, from a ProcMon capture rather than
hivelist— plus one detail on the dialog's wording that I think is worth treating as a bug in its own right.Environment: Windows 11 x64,
Claude_pzs8sxrjxfjjc. Hit across five package versions over ~1 week: 1.37937.1.0, 1.37937.3.0, 1.40609.0.0, 1.40609.1.0, 1.44121.2.0.ProcMon capture at the moment of failure
Filtered to
SHARING VIOLATION/ACCESS DENIED, taken while clicking the Start-menu shortcut:This is @bugale's conclusion observed live at the syscall: container setup fails on
RegLoadKeyof the silo hive, not on anything to do withclaude.exe. AddsSettings\roaming.lockto the set of contended files alongsideUser.dat/UserClasses.dat.The
Explorer.EXE -> claude.exe -> ACCESS DENIEDrows are normal for any MSIX app (unprivileged processes have no read access toWindowsAppscontent) and are unrelated — worth stating explicitly, since that row is what a casual capture will show first and it is a dead end.Everything ruled out, with the command that ruled it out
Posting the full negative space because this thread's history shows people re-walking it. Each of these was checked on my machine during a live occurrence:
| Hypothesis | Check | Result |
|---|---|---|
| A process holds
claude.exe|handle64 "WindowsApps\Claude"| no handles || Something maps the package dir |
Get-Process→.Modulessweep | nothing || Out-of-package children in the container |
GetPackageFamilyName()on every PID | onlycowork-svc|| A process holds the hive |
handle64 -a "User.dat"| no matching handles || Another user session |
Get-AppxPackage -AllUsers| single SID || Partially staged package |
Status,IsPartiallyStaged|Ok,False|| Broken ACLs on the package dir |
Get-Acl| stockTrustedInstaller/SYSTEM|| Deployment stack failure |
Get-AppxLog -All| all operations succeed |On the last one:
Get-AppxLogshowedRegisterByPackageFullNamecompleting in ~313 ms, event 400 "finished successfully", and Windows terminatingCoworkVMServiceitself (9648/9650,0x0) — while launches kept failing. Matches the repeated-Register pattern @maguro29dev and @jerds19 both report.The dialog is independently wrong, and it is expensive
The shell dialog names
C:\Program Files\WindowsApps\Claude_<ver>_x64__...— a file that is not locked and opens fine during the failure. Every diagnostic instinct it triggers is a dead end: process hunting,handle.exe, file locks, AV exclusions, ACLs. I burned about a week on that path before capturing the syscall trace; this thread contains several people who burned considerably longer, including four months chasing filter drivers.Even if the container teardown fix is involved, a launcher that detected
0x80070020and said "Claude needs you to sign out and back in (or unload its stale registry hives) to recover from an interrupted update" would convert a multi-day investigation into a 30-second fix. That seems cheap relative to the root-cause work, and independently valuable given how many duplicate reports this has generated.Note on @bugale's
NtUnloadKey2recoveryWorking here. I've wrapped it in a small PowerShell function that reads
hivelist, reports staleClaudemounts as a health check, and force-unloads them on request — useful because "hives mounted with no package process running" is a much better wedged-state signal than anything process-based. Happy to share if it's of use to anyone; it is @bugale's PoC with a detection front-end and theClaudeStartupcaveat from @J3TH4CK's recipe wired into the failure path.<img width="1070" height="423" alt="Image" src="https://github.com/user-attachments/assets/aa6a05a4-c9c7-49b7-b310-920dde792f96" />
Second machine confirming @bugale's
NtUnloadKey2recovery — worked, no sign-out, no reboot — plus two details that may be useful.Environment: Windows 11 x64,
Claude_pzs8sxrjxfjjc, stealth update 1.44121.2.0 → 1.44121.4.0. Classic presentation: dialog naming...\Claude_1.44121.4.0_..., no package processes alive.Result
App launched immediately afterwards. Matches @bugale's finding precisely, including that leftover
commounts returning0xC0000121(STATUS_CANNOT_DELETE) don't block anything — only the dead silo'suser_sid/user_classes/software/comset matters.Detail 1 — the recovery worked with CoworkVMService still Running
I did not stop the service. It was
Runningthroughout, and the unload plus launch succeeded anyway. Combined with @J3TH4CK's field result that stopping it 4× didn't help, that looks conclusive from both directions: the service is neither the pinner nor part of the cure. Probably worth dropping it from any future mitigation guidance, since "stop CoworkVMService" is the first thing most people (myself included) reach for.Detail 2 — stale silos accumulate across update cycles
Eight mounts across four distinct silo IDs, not one. Only the most recent transition had wedged the app, so the other three were residue from earlier update cycles that had been cleared by sign-out/reboot at the time — the reboot got the app running again but evidently left hive mounts behind. Anything that enumerates and tears down "the outgoing silo" should probably sweep all stale
Claudeentries inhivelist, not just the previous epoch's.Detection signal
Worth noting for anyone scripting this: hives present in
hivelistwhile zero package processes are running is a clean, positive test for the wedged state, checkable before attempting a launch. Every process-based check is a false negative here, as this thread has established several times over. ReadingHKLM\SYSTEM\CurrentControlSet\Control\hivelistforClaudematches needs no elevation.Thanks @bugale — that PoC turned a sign-out into about five seconds.
Another independent occurrence with the identical signature, on a machine that hits it on every stealth update — adding it mainly because the app-side
main.logand the AppModel-Runtime log line up to the second, and because this machine is a Squirrel→MSIX migration (non-virtualised profile), which changes where the orphanedchrome-native-host.exelives.Environment: Windows 11 Enterprise 10.0.26100,
Claude_pzs8sxrjxfjjc,SignatureKind: Developer. Seven updater-driven relaunches between 2026-08-25 and 2026-09-03 (1.34493.1 → 1.37937.0 → .1 → .3 → 1.40609.0 → .1 → 1.44121.2), every one via[stealth-update] Triggering stealth update after idle timeout.main.logreports[MSIX] Filesystem not virtualized — …\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude absent (likely Squirrel upgrade), so the app's profile is the plain%APPDATA%\Claude, not theLocalCachepath.Timeline, 2026-09-03 (local), 1.40609.1 → 1.44121.2
| Time | Source | Event |
|---|---|---|
| 01:29:54–01:30:23 | AppXDeploymentServer | Add of 1.44121.2 with
DeferRegistrationWhenPackagesAreInUse; event 658 deferred registration (1.40609.1 still running) || 01:31:51 | main.log |
[remote-tools-device] keep-awake held— a Cowork remote-tools session was still active || 01:40:53 | main.log |
[stealth-update] Triggering stealth update after idle timeout→[stealth-relaunch] Saved navigation history (43 entries)|| 01:40:54 | main.log |
beforeQuitForUpdate handler fired, going down for update— last line for 5 h 46 min || 01:40:54–01:40:57 | AppXDeploymentServer |
RegisterByPackageFamilyName … ForceApplicationShutdownOption; CoworkVMService terminated; Register event 400 "finished successfully" || 01:40:56 | AppModel-Runtime | 217 Destroyed container for 1.40609.1; 210/211 new container created for 1.44121.2 and process 31836 added; then 215
0x80070020… converting the job ×2 and 2080x80070020[LaunchProcess] — i.e. the updater's own immediate relaunch already fails || 07:15:56–07:18:20 | AppModel-Runtime / AppXDeploymentServer / SCM | Four manual launches. Each: 215/208
0x80070020, thenRegisterByPackageFullName … RepairAppRegistrationOption, event 649 "ACLs repaired successfully … Register next time should succeed", SCM 7045/7040 (CoworkVMService reinstalled, auto→disabled). SCM 7034 "Claude service terminated unexpectedly" at 07:16:32. Nothing written tomain.logby any attempt || 07:19:21 | System 1074 | User-initiated restart |
| 07:19:23 | AppModel-Runtime | 217 Destroyed container
{290A7BD3-…}for 1.40609.1 — the old version's container was alive the whole time, matches @jerds19's observation || 07:27:01 | AppModel-Runtime / main.log | 201 process created;
Starting app { appVersion: '1.44121.2' },[event-loop-stall] update relaunch (stale marker) stands in for an unheard suspend|The previous update on 2026-09-01 (1.40609.0 → 1.40609.1, stealth relaunch at 21:17:55) produced the same 215/208
0x80070020triples at 21:19:30, 21:22:02 and 21:22:03, and the app also only came back after a reboot the next morning.Data points for the analysis above
%APPDATA%\Roaming\Claude\ChromeNativeHost\chrome-native-host.exe, not fromPackages\…\LocalCache\Roaming\Claude\ChromeNativeHost. Any cleanup that keys on theLocalCachepath would miss it here. It is spawned by Chrome at logon, before the app itself starts (today: 07:24:34 vs app start 07:27:01).[Chrome Extension MCP] Failed to copy native host binary: Error: EBUSY: resource busy or locked, copyfile '…\WindowsApps\Claude_<ver>\app\resources\chrome-native-host.exe' -> '…\Roaming\Claude\ChromeNativeHost\chrome-native-host.exe', i.e. the app tries to overwrite the running native host on each launch and can't — consistent with it never being reaped.hivelistafter the reboot still carries eightClaudemounts across four silo ids (Silo5b669f8d…user_sid/user_classes/software/com, plus three older…com/…softwareentries), matching @cplagz's note that stale silos accumulate across cycles even after a reboot "fixes" the launch.Redacted extracts (main.log excerpt covering all seven cycles, AppXDeploymentServer, AppModel-Runtime with the hivelist dump, SCM and Application events, environment) attached in a follow-up comment.
Another machine with the same signature, adding two data points the thread does not have yet: (1) the app's own child-process counter in
main.logpredicts which stealth updates will wedge, and (2) on this machine the likely job member is a plugin daemon that a SessionStart hook starts inside the container (claude-mem worker), i.e. the same mechanism as thegit fsmonitor--daemoncase in #91763 with a different culprit.Environment: Windows 11 Home 10.0.26200,
Claude_pzs8sxrjxfjjc(SignatureKind Developer, Squirrel-to-MSIX migrated profile:main.logsays[MSIX] Filesystem not virtualized), bundled Claude Code 2.1.255 / 2.1.258,ClaudeStartupStartupTask disabled. Nine stealth updates between 2026-08-18 and 2026-09-03, four of them ended in "dead until reboot".1.
[process-memory] children(N)right before the stealth update predicts the outcomemain.logwrites[process-memory] ... electron(N)=... children(N)=...about once a minute. Last such line before each[stealth-update] Triggering stealth update after idle timeout:| Date (local) | Transition | children(N) before quit | Result |
|---|---|---|---|
| 08-18 15:24 | 1.30096.5 to 1.32352.1 | 0 | relaunched in 31 s |
| 08-19 02:22 | 1.32352.1 to 1.32885.1 | 0 reported (see note) | dead until reboot on 08-20 14:45 |
| 08-21 02:01 | 1.32885.1 to 1.34493.0 | 0 | relaunched in 1 s |
| 08-21 06:11 | 1.34493.0 to 1.34493.1 | 0 | relaunched in 1 s |
| 08-26 15:22 | 1.34493.1 to 1.37937.1 | 0 | relaunched in 34 s |
| 08-27 02:33 | 1.37937.1 to 1.37937.3 | 0 | relaunched in 35 s |
| 08-29 12:10 | 1.37937.3 to 1.40609.0 | 0 reported (see note) | dead until reboot 12:18 |
| 09-01 20:35 | 1.40609.0 to 1.40609.1 | 164 (2956 MB) | dead until reboot 20:48 |
| 09-03 01:01 | 1.40609.1 to 1.44121.2 | 118 (3821 MB) | dead until reboot 16:37 |
Note: the first build that ever reported a non-zero
childrenvalue here is 1.40609.0, so the two zeros on failed cycles may be the counter rather than reality. Every relaunch that succeeded had no session tree; both cycles with a measured large tree failed. In the failed cycles the log ends atbeforeQuitForUpdate handler fired, going down for update/Windows session ending (close-app) - quitting the appand the next line isStarting appafter the reboot, withupdate_relaunch_marker: 'stale'.2. AppModel-Runtime/Admin timeline for 2026-09-03 (local time)
{B8B23368-...}of 1.40609.1. That container was created at logon (09-01 20:48:38) withcowork-svc.exeas the process added in 210/211, so it is the packaged service's container, not the app's. On this machine every epoch has two containers, one forCoworkVMServiceand one for the app; worth knowing when pairing 210/217.0x5) for 1.40609.1, event 2150x80070020 ... converting the jobfor 1.44121.2, then 210/211 create{DC0D3BB7-...}with process 26116, then 215 and 2080x80070020 [LaunchProcess]at 01:01:40. Nothing reachesmain.log.{BE2239B1-...}+ 215 x2 + 208. TWinUI 1621 reports both activations as successful.{B8B235C3-...}, the app container of 1.40609.1 created on 09-01 20:50:20 with the app's main process 27012. It stayed alive 15.5 hours after the app quit and was destroyed only by the user's reboot at 16:37.The 09-01 cycle is identical: old app container
{31E03264-...}of 1.40609.0 destroyed only at 20:47:46 during the reboot, 215/208 for every launch attempt at 20:36:25 and 20:46:33-34.3. What is in the container job on this machine, and what is not
Checked on the healthy post-reboot instance with
IsProcessInJob(hProcess, NULL)andGetPackageFullName:%APPDATA%\Claude\claude-code\2.1.258\claude.exe, spawned by the main process) is in a job, and so is every child it spawns:ssh.exe,cmd.exe,node.exe,pwsh.exe,uv.exe,conhost.exeand third-party MCP server executables. None of them has package identity (APPMODEL_ERROR_NO_PACKAGE). That is the #91763 mechanism, and it covers every MCP server, shell and SSH tunnel a session starts.node.mojom.NodeServiceutility processes (pwsh.exe,conhost.exe) are not in a job. So the app already has a spawn path that breaks away from the container; the Code-tab CLI just does not use it.bun.exe ... claude-mem/.../worker-service.cjs --daemon(the claude-mem plugin's worker). It was started 11 s after the app by a SessionStart hook of a Code-tab session, its parent is already dead, it is in a job, has no package identity, and is designed to outlive sessions.git fsmonitor--daemonis not present here (core.fsmonitorunset), so #91763's culprit is one instance of a general class: anything a hook or MCP server daemonises inside the container survivesForceApplicationShutdownand pins the old silo. Orphaned MCP server processes from long-closed sessions (a dozentelegram-mcppython processes on 08-25) have also been seen on this machine, so there is never a shortage of job members.Suggestions
quitForUpdatewhilechildren(N) > 0, or terminate the app's own container job members first.CREATE_BREAKAWAY_FROM_JOB, the way the utility-process path already ends up outside the job.Next occurrence I will kill the orphaned job members (dead parent + in job + no package identity) before trying @bugale's hive unload, and report which of the two clears it.
Another machine with the same signature (1.40609.1.0 → 1.44121.4.0 on 2026-09-03, and 1.40609.0.0 → 1.40609.1.0 on 2026-09-01), adding one data point I don't see in the thread yet: the app-side reason the process tree survives.
main.logshows the stealth-update quit runs none of the cleanup steps a normal quit runs. Same day, same install:Counts over the last four quits on this machine: normal quits 31 and 31, stealth-update quits 0 and 0. The normal path is where MCP servers, plugin servers, LAM sessions and pty hosts are shut down, so on the stealth path the 57 children are left to Restart Manager, which waited its full 30 s (
Gap: 33438 msin the AppXDeploymentServer performance summary) and did not get all of them: the old version's container{CEA01A24-…}was destroyed at 21:44:38, one second before the logoff notification, 40 minutes after the package had been swapped.Corroborating the rest of the thread: 215/208
0x80070020on every launch (13 attempts, six automatic repair registrations all "finished successfully"), the PackagedService container created fine each time, sign-out sufficed (no reboot),ClaudeStartupStartupTask disabled here, Squirrel-migrated profile ([MSIX] Filesystem not virtualized). Nogit fsmonitor--daemonon this machine (core.fsmonitorunset everywhere); the candidates here are MCP servers started throughuvx/nodewrappers and a Codexnode_repl.exeruntime, all long-lived detached children of the Code tab.One more thing, for whoever looks at the updater side: the deferred registration attempted at a normal launch (
Stage+RegisterByPackageFullName, no force option) failed0x80073D02becausecowork-svc.execounts as the package being in use, so the deferred path can never complete on a machine where the service auto-starts, and every update goes through the forced stealth path (#89599 covers that side).Suggested fix on the app side: run the
onQuitCleanupchain (or at least its child-process shutdown steps) onbeforeQuitForUpdateand wait for the tree to end before the update proceeds. Full timeline, event-log exports and an unprivileged\Container_*job enumerator available on request.Adding one small diagnostic detail I don't see in the thread, from another 10.0.26200 machine that hit this on 1.40609.1.0 -> 1.44121.4.0 (2026-09-03, app dead 13:32->17:00, cleared by reboot). @bugale's hive analysis matches what I captured.
Microsoft-Windows-TWinUI/Operational1621 reports every failed activation as a success. During the 3.5h outage an external watchdog re-activated the app viashell:AppsFolder\Claude_pzs8sxrjxfjjc!Claudeevery 10 minutes, 21 times. All 21 died at AppModel-Runtime 215/2080x80070020— but each logged:because 1621 reports only that the activation request was dispatched.
Consequence: there is no success/failure signal at the activation call site.
Start-Process shell:AppsFolder\...returns 0, TWinUI says success, and the app simply never appears. Any automated recovery has to poll for the process and then read AppModel-Runtime 208/215 to learn why.That's an argument for surfacing
0x80070020instead of dying silently — it would turn "clicking the icon does nothing" into something diagnosable.I also confirm the two refuted mitigations on this machine:
CoworkVMServicewas Running throughout the failure (and is Running now, post-recovery), and noWindowsApps\Claude_*process existed during it.Same failure mode here on Windows 11 (26200), MSIX install from the Store.
Three idle-triggered stealth updates in two days, two of which needed a reboot:
| KST | Version | Outcome |
| --- | --- | --- |
| 2026-09-03 13:29 | 1.40609.1.0 → 1.44121.4.0 | relaunched on its own ~20s later |
| 2026-09-04 15:09 | 1.44121.4.0 → 1.46388.1.0 | never came back; reboot |
| 2026-09-04 21:07 | 1.46388.1.0 → 1.46388.2.0 | never came back; reboot |
All three start the same way in
%LOCALAPPDATA%\Claude\logs\main.log:On the third one Windows surfaced the sharing violation directly as a dialog —
"이 파일을 다른 응용 프로그램에서 사용 중입니다" (this file is in use by another
application), pointing at
C:\Program Files\WindowsApps\Claude_1.46388.2.0_....That matches the
0x80070020in this issue.Data point on the orphan mechanism
I think I can name one of the survivors on my machine. I use the Code tab heavily,
and Claude Code had started a long-running
nodedev server for my project. Itsparent chain is:
So it is orphaned but alive, is not named
claude.exe, and would not show up underTask Manager's "Claude" group — exactly the profile described in this issue. A server
like that was running during the 21:07 failure.
Caveat so this is not overstated: I captured that parent chain from a freshly started
server after recovery, not from the failing moment, and I did not verify job-object
membership. So it shows these processes do get orphaned and outlive their parent, not
that this specific one held the container.
The service, which behaves differently here than in the note above
A comment above lists
CoworkVMServiceas a refuted mitigation because it stayedRunning throughout the failure. On this machine it did not. The System log shows
7034 ("Claude 서비스가 예기치 않게 종료되었습니다") in both failures, at 15:28:09 and
21:17:34 KST, and not at all on 9/3 when the update succeeded. So the service may
behave differently across machines rather than being uniformly irrelevant.
Related, and I have not seen it mentioned in the thread — this is about the service's
recovery configuration, not about whether it was running. The service is reinstalled
on every update (7045/7040 pairs) and each time logs to the Application log:
sc qfailure CoworkVMServiceconfirms zero failure actions are registered(
RESET_PERIOD: 0). The service runs as LocalSystem but is apparently configured by acaller without the rights to set recovery actions. Where the service does die, that
would be a second, independent reason a reboot is the only recovery — Windows is never
asked to restart it.
Environment note
Offered as data rather than a hypothesis: a VPN (ProtonVPN) auto-connects at boot, so
the app always launches with it up, and I disconnect it shortly after I start working.
I have no evidence tying that to this failure — the
0x80070020path is local filelocking, not network — but the app consistently outlives a network transition on this
machine, which may be worth knowing if anyone else here has the same pattern.
Ruled out on my side, in case it saves anyone time: no BSOD or Kernel-Power events, no
Resource-Exhaustion warnings, app memory ~2.2 GB of 32 GB, 65 GB free disk.
Fourth occurrence this morning, and it adds a few things to what I posted above.
1.46388.2.0 → 1.46388.3.0, 2026-09-05 09:25:46 KST, same [stealth-update] Triggering stealth update after idle timeout. Same file-in-use dialog (0x80070020) pointing at C:\Program Files\WindowsApps\Claude_1.46388.3.0_.... Three of the four have now needed a reboot.
Killing claude.exe from Task Manager did not help. I tried that before rebooting — the app still would not launch. Whatever holds the container is not claude.exe, which lines up with the orphan description in this issue: not named claude.exe, not in Task Manager's "Claude" group. Only the reboot recovered it.
No CoworkVMService crash this time. In the two failures I described earlier the System log had 7034 for that service; this time it does not — only the usual 7045/7040 reinstall churn at 09:26:23, 09:28:27 and 09:28:58. So the service dying is not required for this failure. It may be a second, independent way to get stuck rather than the cause of this one; I'd treat my earlier service note as a separate issue from the container problem.
On my dev server, which I offered above as a candidate survivor — the evidence now points the other way. This time the app's own shutdown killed it:
09:25:46 [CCD] Killing 1 PTY process tree(s) on quit
09:25:46 Stopping shell PTY for session local_...
and after recovery there were zero node.exe processes. So at least for a process started by Claude Code in a normal terminal session, the PTY tree kill does reach it. Please discount that part of my earlier comment.
One environment variable I can now rule out. In my earlier comment I noted that a VPN auto-connects at boot and that I usually disconnect it once I start working, so the app normally outlives a network transition. Today I kept the VPN connected the whole time — through launch, through the update, through recovery — and the failure was identical. So the network transition is not involved.
Another independent reproduction, with a different survivor and a no-reboot, no-elevation recovery that lines up with #91763 and #92167.
Environment: Windows 11 Pro 10.0.26200, Claude Desktop MSIX
Claude_pzs8sxrjxfjjc, standard non-admin user. Update1.46388.2.0->1.46388.3.0(the fourth stealth relaunch in 48 h on this machine:.1,.2,.3all shipped within a day).Sequence (local time, 2026-09-05):
Every manual launch afterwards (Start menu and
shell:AppsFolder\Claude_pzs8sxrjxfjjc!Claude) repeated 215/208, and each attempt stopped and reinstalledCoworkVMService(System log 7040/7045) without effect.winget(DesktopAppInstaller, also a Desktop AppX) launched fine from the same session, so the container machinery itself was healthy.What was holding it. The second container of the old version,
{2414F87F-...}for1.46388.2.0(the oneclaude.exeitself ran in, created 00:52:51 at the previous relaunch), never got its 217. The Helium hive was still mounted and file-locked:No process carried the package identity (
tasklist /appsempty for Claude). Enumerating processes whose parent PID is dead and checkingIsProcessInJob(h, NULL)found the survivor:It was a static dev server started by a Claude Code session hosted in the desktop app (a Bash tool call that backgrounded it). Not a PTY tree, so
beforeQuitForUpdatenever touched it.Stop-Process -Id 7824-> AppModel-Runtime 217 for{2414F87F-...}fired the same second, theUser.datopen-for-exclusive test immediately succeeded, and the next launch produced 201 (Created process ... 1.46388.3.0). The app is running normally on 1.46388.3.0 now. No reboot, no elevation, no service changes.A red herring worth noting: an orphaned
chrome-native-host.exe(spawned by Chrome for the browser extension on 09-03 from the1.46388.1.0cache path) was also alive. Killing it cleared the[Chrome Extension MCP] Failed to copy native host binary: EBUSYerrors in main.log but did not release the container. The container holder was only the non-PTYnode.exechild.Quick non-admin triage that worked here, for anyone hit by this before a fix ships:
Same asks as the thread: break Claude Code's non-PTY children out of the container job (or terminate the whole package job on
beforeQuitForUpdate), and don't fire the stealth relaunch while the old container still has members. The generic "Another program is currently using this file" dialog should at least name the PID that is pinning the container.Another occurrence on current versions (1.46388.4.0 → 1.49585.0.0, 2026-09-09), with one data point this thread doesn't have yet: self-recovery without reboot, sign-out, or any manual cleanup — the wedge cleared itself ~6 minutes after the failed launch, as soon as the old container was destroyed.
Environment: Windows 11 Education 10.0.26200,
Claude_pzs8sxrjxfjjc, Claude in Chrome connected (chrome-native-host.exealive since before the update).Timeline (local time, from event logs):
{13C6C86A-…}RegisterByPackageFamilyName+ForceApplicationShutdownOption; event 400 register finished successfully in 1.1 s0x80070020 … error encountered converting the job; plus event 67 failing with0x5while modifying the old package's status{13C6C86A-…}(alive since 20:07) is destroyed on its ownAgrees with the thread on the key mechanics: successful (re)registration does not clear the wedge (register succeeded one second before the 215/208 pair), and the failure window is exactly [forced registration → old-container teardown].
The pre-update
chrome-native-host.exeinstance was gone by the time I inspected (the current one respawned at 21:54:05, seconds before the app's next start); I did not capture what ended it, so I can't say whether its exit is what released the container here — but its lifetime spanning the update is consistent with the forensic snapshot above.Implication for the fix: the wedge is not always terminal. A post-update launcher that detects
0x80070020and retries with backoff after awaiting/verifying old-container teardown would have made this occurrence completely invisible to the user — instead the user got a launch error that resolved itself minutes later for no visible reason.Three additions the thread doesn't have yet: a negative-control machine, the
event signature that separates a wedging update from a non-wedging one, and an
app-side fix with an existence proof. Everything about the Helium hives / silo
(@bugale, @cplagz) and the ruled-out mitigations (@J3TH4CK) matches here and I won't
restate it.
Environment: Windows 11 Pro 10.0.26200,
Claude_pzs8sxrjxfjjc(SignatureKind:), Cowork enabled, Claude Code used inside the desktop app daily.Developer
Frequency: 10 of the last 12 updates wedged (2026-08-26 → 09-14,
1.34493.1→1.52386.6). Recovery each time: sign out and back in (~4 s), nine times.1. A second machine that never wedges — same day, same version bump, opposite outcome
A colleague's machine runs the same MSIX package family, the same versions, and the same
[stealth-update]code path (hismain.loghas 8 ×stealth-update/ 8 ×beforeQuitForUpdate). Over a 12-dayAppModel-Runtime/Adminwindow he took 4 updates(09-07, 09-09, 09-11, 09-14) and logged 0 events 215.
The cleanest pair is 2026-09-14,
1.52386.3.0 → 1.52386.6.0, both machines the same day:| | mine | colleague |
|---|---|---|
| outcome | 215 ×2 + 208, dead until sign-out | launched normally, 0 × 215 |
| update path |
[stealth-update]|[stealth-update]|| window total | 12 updates / 10 wedged | 4 updates / 0 wedged |
Same app version, same version bump, same day, same code path, opposite results — which
rules out the package/payload and leaves a per-machine timing difference.
2. What actually separates them: which containers get destroyed inside the Register window
The discriminator is visible in
AppModel-Runtime/Adminevent 217 during theRegisterByPackageFamilyNamewindow. Container ownership is readable from the containername in the 210 event data:
<pkgfullname>-S-1-5-21-…is the per-user container,<pkgfullname>-PackagedServiceis the packaged service's.Colleague, 09-11
1.49585.0.0 → 1.52386.0.0— succeeds:That old user container had been alive 24 h 49 min.
Mine, 09-14
1.52386.3.0 → 1.52386.6.0— wedges:So: old user container destroyed inside the Register window ⇒ success; only the service
container destroyed ⇒ wedge. The most likely reading is that
ForceApplicationShutdownOptiononly tears the container down when it still finds the appprocess alive — on my machine the app is gone within ~1 s of
beforeQuitForUpdate, on hisit is still there ~37 s later. I can't prove the app-exit latency directly from logs, but
the 217 signature itself is checkable by anyone in this thread.
3. The container is a logon-session object — it is not "pinned" by a process
Two measurements that I think reframe the "who is the pinner" question:
machine
085C318Clived 2026-09-09 09:28 → 09-11 10:45 (sign-out) — 2 days, across twofull app quits and three launches; each relaunch only joined it (event 211 with no new
210). A second one lived 10 h 36 min and outlived the app's quit by 2 h 20 min. The
colleague's lived 24 h 49 min. This looks like normal warm-container behaviour, not a leak.
after the 215s on 09-11 enumerated package identity via
GetPackageFamilyNameFromTokenover all 427 processes: zero processes with
Claude_*identity, and noclaude.exeanywhere in the process table.
So "an orphaned member pins the job" isn't required for the wedge. Consistent with that,
on this machine:
| candidate | result |
|---|---|
|
chrome-native-host.exe| not running at the 09-05 and 09-09 wedges (its own log shows it had exited hours earlier) ||
children(N)/ open sessions | wedged with only 2, 3 and 5 PTY trees; meanwhile non-update quits with 8–9 trees released the container in 10–12 s ||
RuntimeBroker.exe(old package identity, parentsvchost) | present at 2 of 3 captured wedges, absent at the third → not necessary |I'd read @J3TH4CK's
chrome-native-hostand #91763'sfsmonitor--daemonas real jobmembers that make things worse (they extend the epoch), but not as the necessary cause.
4. The app-side fix, with an existence proof
Current sequence is:
[stealth-update]→ app quits itself → `RegisterByPackageFamilyNameforced shutdown has nothing left to shut down, the old user container is never torn down,
and the new version's container setup hits the still-mounted hives.
Suggested change: don't self-quit before the register — issue the register while the app
is still running and let
ForceApplicationShutdownOptionterminate it. That pathdestroys the old container as part of the shutdown, which is exactly what makes the
colleague's machine succeed 4/4.
It also already worked once on my machine, by accident: on 2026-09-03 08:14 the
deployment's two 217s landed 0.87 s after
beforeQuitForUpdate— the app was caughtmid-quit, both containers went down, and the update completed with 0 × 215. That is the
same code path succeeding when the shutdown wins the race.
This needs no Windows-side change and no user workaround, and it would make the
NtUnloadKey2/ sign-out recipes in this thread unnecessary rather than mandatory.Another machine, on 2.110.0.0. 1.49585.0.0 -> 2.110.0.0 on 16/09/26, same wedge. I am adding only what is not in the thread yet. The hive and silo side from @bugale and @cplagz matches and I will not repeat it. Every line below is a direct read from this machine's logs. Anything I did not check says so.
Environment: Windows 11 Home 10.0.26200,
Claude_pzs8sxrjxfjjc, SignatureKind Developer,[MSIX] Filesystem virtualization active, bundled Claude Code 2.1.260 -> 2.1.271. One Code tab session open with seven stdio MCP servers. I rebooted before I had read this thread, so I have no hivelist or job snapshot from the wedged state.1. Timeline (16/09/26, local)
| Time | Event |
|---|---|
| 09:19:12 | During-logon registration of 1.49585 (staged 09/09/26; app closed since 09/09/26 17:07 after a full clean quit).
ForceTargetApplicationShutdownOption, 613 gap 15 ms, one 217 for the service container. App launched 09:19:14. No 215. || 09:19:47 | App updater fetched 2.110 from
downloads.claude.ai. 09:20:18 and 09:28:40: 638/658 deferred, app running. || 09:41:07 | Windows retried the deferred registration itself, mid-session, during a Windows Update pass (event 821; WER
StoreAgentInstallFailure1fromUpdate;MoUpdateOrchestrator).0x80073D02, app running. || 09:48:03 | Last
[process-memory]:electron(13) children(14). || 09:48:19 |
[stealth-update] Triggering stealth update after idle timeout,Killing 1 PTY process tree(s),beforeQuitForUpdate,Windows session ending (close-app). Last main.log line until after the reboot. || 09:48:20 | 603
RegisterByPackageFamilyName+ForceApplicationShutdownOption. || 09:48:55 | 217 for the service container only. Event 67
0x5on the old package. Application Hang 1002 onconhost.exe. || 09:48:57 | 400 finished successfully. 613: overall 37,328 ms, gap 35,390 ms. 215 x2 + 208
0x80070020for 2.110. Nothing reached main.log. || 10:55:55, 10:56:28 | Two manual launches. Each: Register with
RepairAppRegistrationOptionsucceeded, 215 x2 + 208, TWinUI 1621 "completed successfully". || 10:57:03 | Reboot. 217 for the app's user container, created 09:19:14, 68 minutes after the app quit. The 09:28 relaunch had joined that container (211, no new 210). |
| 11:11:14 |
Starting app { appVersion: '2.110.0' }. Fine since. |2. What this adds
children(14)at quit, one PTY tree killed. The non-PTY members here are the MCP servers: each stdio server runs ascmd.exe -> node.exe (npx) -> cmd.exe -> node.exewith its own conhost, one set per open session. Which member survived: not checked.0x80073D02. Seven minutes later the idle timer did it the wedging way. The week-old 1.49585 only applied at today's logon, which matches the "left for a logon" reading.cowork-svc.exe: its container ran 09:48:57 to 10:55:56 and every Register restarts it. PID not recorded, so this is a match on size, name and timing only. It agrees with the thread: the service is neither the pinner nor the cure.chrome-native-host.exeran fromPackages\...\LocalCache\Roaming\Claude\ChromeNativeHost\from 09:19:50 to the reboot, per its own log. Present across the transition. Not tested as the holder.3. One note on the dialog
I read the
0x80070020text as "the application is being used elsewhere" and spent my first pass on the single-instance lockfile. Dead end. If a maintainer changes one thing first, make that dialog name the container problem.Another repro on 2.110.0.0 (1.52386.6.0 → 2.110.0.0), Windows 11 Home 10.0.26200, standard non-elevated user. The same machine hit this twice in 5 days, both times with the same kind of survivor, so I'm posting only the concrete data points.
Survivor both times: a background server started by the Desktop Claude Code session's Bash tool
cd work && (python serve.py > serve.log 2>&1 &)through the Bash tool (Git Bash) in a scratch workspace. The subshell exits immediately, sopython.exeis orphaned (parent PID gone) but stays in the app's job.[stealth-update] Triggering stealth update after idle timeout→[CCD] Killing 2 PTY process tree(s) on quit→beforeQuitForUpdate handler fired, going down for update. The python server (listening on 127.0.0.1:8765) was not in a PTY tree and survived.{C83592A4-…}(1.52386.6.0, event 210 at 2026-09-15 07:26:24) never got a 217.hivelistkept\REGISTRY\WC\Silo…user_sid→…\Packages\Claude_pzs8sxrjxfjjc\SystemAppData\Helium\User.datmounted.0x80070020(2026-09-16 18:33:15; 2026-09-17 18:54:49, 18:54:51, 19:04:07, 19:04:09).python -m http.server 8765, also started in the background by a Desktop Code session.Detection: the survivor has no package identity (
GetPackageFullNamereturns no package,tasklist /appsdoesn't list it), so it can't be found by package. What worked: an orphaned process (dead parent) created after the old container's event 210, while the old version was running.Negative result:
Stop-Service CoworkVMService(allowed without elevation) did not help. The next launch still failed with 0x80070020, and the service was started again automatically.Recovery without reboot or elevation:
Stop-Process -Id <python pid>→ event 217 for{C83592A4-…}at 19:11:04,Helium\User.datgone fromhivelist, next launch at 19:11:15 → 210/211/201, and the app booted normally.Suggestion: quit-for-update only kills PTY trees, but background processes started by the Bash tool (
(cmd &)) remain in the app's job. Terminating everything in the job before the update, or not firing the stealth update while non-PTY processes are still in the job, would prevent this. On a 0x80070020 launch failure, naming the PID that pins the old container would also be far more useful than the generic "another program is using this file" dialog.