Windows MSIX app: auto-update during app hang corrupts package registration (launches fail 0x3CFC); Settings Repair can never succeed (source MSIX deleted from %TEMP%)

Status Open
Reported on v2.1.219
Maintainer reply None cached
Activity 4 comments · opened Jul 29, 2026

Environment

  • Claude desktop app 1.24012.9.0 — MSIX, package family Claude_pzs8sxrjxfjjc, SignatureKind=Developer (direct download from claude.com/download, not Microsoft Store)
  • Bundled Claude Code CCD: 2.1.219 ([CCD-autoupdate] Disabled: MSIX install)
  • Windows 11 Home 10.0.26200, 32 GB RAM, hybrid Intel/NVIDIA HP laptop

Summary

Long heavy sessions hang the app (memory leak — Windows' RADAR_PRE_LEAK_64 has fired on claude.exe monthly since April 2026 across four app versions: 2.1.111.0 → 1.7196.0.0 → 1.13576.0.0 → 1.24012.x, with hard MoAppHang events following on 2026-06-17 and 2026-07-24). While the hung process is still alive, the app's ~4-hourly auto-updater delivers the next MSIX. Registration is deferred:

AppXDeploymentServer event 658 (2026-07-23 10:15): Marking package {Claude_1.24012.1.0_x64__pzs8sxrjxfjjc} for deferred registration because {Claude_1.21459.0.0_x64__pzs8sxrjxfjjc} is still running. Same again 2026-07-24 12:28 for 1.24012.9.0 vs 1.24012.1.0.

The package is left half-registered (deployment log later shows event 649 repairing broken ACLs on the package folder). From then on every launch fails:

AppModel-Runtime event 6, error 0x3CFC (ERROR_NEEDS_REMEDIATION): Cannot create the process for package <NULL> because an error was encountered while checking the machine-level package status. The application cannot be started. Try reinstalling the application to fix the problem.

15 consecutive failed launch attempts logged on 2026-07-28 (13:26, 14:00, 15:21 — 5 rapid retries each). AppXSvc also intermittently failed to start with 0x8007045B in bursts on the same days.

Why Settings → Repair can NEVER succeed for this app

Windows repairs an MSIX by re-staging from the recorded install source. For this app that source is the self-update temp file, e.g. file:///C:/Users/<user>/AppData/Local/Temp/Claude-1973497450.msixwhich is deleted after installation. Every repair attempt therefore fails:

  • Event 402: error 0x80070002: Reading manifest from location: Claude-<id>.msix failed with error: The system cannot find the file specified.
  • Event 666: Add operation result 0x80073CF0 (ERROR_INSTALL_OPEN_PACKAGE_FAILED)

On 2026-07-24 repair additionally failed with 0x80073D02 (ERROR_PACKAGES_IN_USE) because the hung claude.exe was still alive, plus event 8107 Illegal non-AppStore or non-AppInstaller package integrity validation and event 8104 trust-label failure 0x80070057.

So the recovery path Windows itself suggests ("Try reinstalling / Repair") is a guaranteed dead end, and the only thing a normal user discovers is full uninstall + reinstall — which wipes the app-side session sidebar (LocalCache) and looks like catastrophic data loss. This user reinstalled three times in one week believing all sessions were gone each time.

Observed sequence

  1. Multi-hour heavy session → UI hang (fresh install already reaches ~1.8 GB tree RSS across 10 Electron processes within 27 minutes, per the app's own [process-memory] telemetry in main.log)
  2. Auto-updater stages the next version while the hung old version is still running → event 658 deferred registration
  3. Hung process is killed / dies → all launches fail with 0x3CFC
  4. Settings → Repair → 0x80070002 / 0x80073CF0 (source MSIX gone)
  5. Full uninstall + reinstall is the only recovery a user can find

Workaround that recovers without reinstalling (for anyone else hitting this)

# kill all claude/cowork-svc/chrome-native-host processes first, then:
$pkg = Get-AppxPackage -Name Claude
Add-AppxPackage -Register "$($pkg.InstallLocation)\AppxManifest.xml" -DisableDevelopmentMode -ForceApplicationShutdown

Reset-AppxPackage also works (Repair never will).

Asks

  1. Don't stage/register an update while an existing app process is running or hung — or force-close it first, the way the manual installer path already does (ForceApplicationShutdownOption).
  2. Keep the installer MSIX (or register a durable repair source) so Windows' Repair function can actually work.
  3. Fix the underlying renderer/utility memory leak that causes the hangs.

Related: #42962 (idle RAM leak), #28900 (hang after hours; restarts degrade until app won't start), #42776 (orphaned process holds file lock on WindowsApps exe), #23637, #55465.

All error codes and event IDs above were read from Microsoft-Windows-AppXDeploymentServer/Operational, Microsoft-Windows-AppXDeployment/Operational, Microsoft-Windows-AppModel-Runtime/Admin, and the Application log on the affected machine.

🤖 Diagnostics gathered with Claude Code

View original on GitHub ↗

4 Comments

mrsoone · 1 month ago

Update: further diagnosis supersedes the memory-leak framing, and corrects two claims in my original report

I ran a full read-only diagnostic on this machine and then successfully recovered the package in place. The results change the picture. Posting this as a correction rather than editing the body above, so the original reasoning stays visible.

The memory-leak framing is superseded

I no longer have evidence that a leak causes this. Over a 90-day window the machine logged zero display-driver TDR events, zero WHEA hardware errors, zero bugchecks and zero unexpected shutdowns. Only three claude.exe hangs exist in that window (2026-06-17, 2026-07-24, and none since), all with hang type Top level window is idle and no faulting module. That is a UI thread that stopped pumping messages, which is not by itself evidence of a leak. Ask #3 in the original body should be treated as unsupported until someone reproduces it with better data.

Correction 1: uninstall and reinstall does NOT reliably fix it

The original body says full uninstall and reinstall is the only recovery. On this machine that turned out to be false. The deployment log shows a clean uninstall and reinstall completing on 2026-07-28:

16:39:21  Remove operation on Claude_1.24012.9.0_x64__pzs8sxrjxfjjc ... finished successfully
16:41:51  Add operation, main parameter Claude-212603631.msix
16:41:55  Add operation ... finished successfully

No 8104 or 8107 errors were logged during that install. It was clean. The package still came up Status: Modified, NeedsRemediation and still would not launch.

Correction 2: Add-AppxPackage -Register alone did not clear the state

The workaround in the original body is incomplete. I ran it twice from an elevated session against a dynamically resolved manifest, with zero package processes running:

Add-AppxPackage -DisableDevelopmentMode -Register "<InstallLocation>\AppxManifest.xml"

Both runs reported success at the deployment layer, with no exception thrown:

Deployment Register operation with target volume C: on Package Claude_1.24012.9.0_x64__pzs8sxrjxfjjc
  from: (AppxManifest.xml) finished successfully.
Performance summary ... Overall time: 234 ms

Status remained Modified, NeedsRemediation after both. Activation via IApplicationActivationManager::ActivateApplication returned 0x80073CFC (ERROR_PACKAGE_NOT_FOUND) even though Get-AppxPackage and Get-StartApps both resolved the package and the AUMID correctly, and app\Claude.exe was present on disk.

What actually recovered it was Windows' own repair path running repeatedly. Activation attempts triggered:

603  Started deployment RegisterByPackageFullName operation ...
       Options ForceTargetApplicationShutdownOption,RepairAppRegistrationOption
649  Trying to repair ACLs for \\?\C:\Program Files\WindowsApps\Claude_1.24012.9.0_x64__pzs8sxrjxfjjc
649  ACLs repaired successfully ... Register next time should succeed.

After several of those cycles the status flipped to Ok and the app launched with a real window. So the broken-ACL condition noted as an aside in the original body appears to be closer to the actual blocker than the trust-label failure was.

Machine-level context that likely explains the persistence

This machine has a corrupt Windows StateRepository. Microsoft-Windows-StateRepository/Operational logs:

Event 100, Error 0x15: misuse at line 185353 of [737ae4a347]

0x15 is SQLITE_MISUSE. It fired 95 times in 14 days, and it fired on every single one of my register and activation attempts tonight (19:38:24, 19:39:56, 19:40:43, 19:41:34, 19:41:59, 19:43:30, 19:44:19, 19:44:52).

This is not Claude specific. The same servicing stack is failing for other packages on this machine, with 93 to 194 AppxDeployment failures per day:

  • Microsoft.YourPhone failed to install, 0x80073D02
  • AD2F1837.OMENCommandCenter failed to install, 0x80073D02
  • MicrosoftWindows.Client.WebExperience failed to install, 0x80073D02
  • MdOdrMcpFilterPackage looping on 0x80073D0B, 36 occurrences
  • Microsoft.GamingApp and Microsoft.WindowsStore hardlink warnings, event 1230

So the honest reading is: a damaged StateRepository on this machine made the package registration unrecoverable by the normal paths, and the app's update-over-running-instance behavior is what kept walking into it. I cannot claim the updater alone caused the unlaunchable state.

The ask, unchanged and still worth doing

The event 658 deferred-registration sequence is real and reproducible on this machine, across three version bumps in two days, each attempted while the previous version was still running:

2026-07-23 10:15  Marking package {Claude_1.24012.1.0} for deferred registration
                    because {Claude_1.21459.0.0} is still running.
2026-07-24 12:28  Marking package {Claude_1.24012.9.0} for deferred registration
                    because {Claude_1.24012.1.0} is still running.
2026-07-24 14:22  error 0x80073D02: Unable to install because the following apps
                    need to be closed Claude_1.24012.9.0
2026-07-24 14:22  8107 Illegal non-AppStore or non-AppInstaller package integrity
                    validation attempted
2026-07-24 14:22  8104 Failed to set the Trust Label ... Error: 0x80070057

Two requests stand:

  1. Do not register a new version while an existing instance is running. Force-close first using ForceApplicationShutdownOption, the way the manual installer path already does, rather than deferring registration and leaving a half-applied state.
  2. Detect and recover a trust-label or registration failure instead of leaving the package in Modified, NeedsRemediation, which is a state the user-facing Repair and Reset buttons cannot clear.

A third, cheaper suggestion: when registration is deferred or fails, surface it to the user in-app. The only reason this was diagnosable at all was the deployment event log, which no ordinary user will read.

Environment

  • Claude desktop 1.24012.9.0, MSIX, package family Claude_pzs8sxrjxfjjc, SignatureKind=Developer (direct download, not Store)
  • Windows 11 Home 10.0.26200
  • Recovered in place, currently Status: Ok and running

Corrections above are from the same machine as the original report. Anything I could not verify, I have said so rather than asserted.

mrsoone · 1 month ago

Second correction: recovery attribution and the database-corruption claim

Follow-up from the same machine after a full post-mortem of the deployment logs. Three findings correct my previous comment, and one new data point sharpens the original asks.

1. The proximate recovery was a user-initiated reinstall, not the repair path. My previous comment credited the repeated ACL-repair cycles (event 649) with flipping the package to Ok. Retracing the deployment timeline shows the state actually cleared with the reinstall I ran at 19:44 on 2026-07-28. The repair cycles were not what recovered the package.

2. The StateRepository is not corrupt. Both databases (StateRepository-Machine.srd and StateRepository-Deployment.srd) were subsequently copied via VSS snapshot and passed PRAGMA integrity_check with ok. The "damaged StateRepository" framing in my previous comment is withdrawn.

3. Event 100 (SQLITE_MISUSE) does not discriminate between success and failure. It fired on the successful 19:44 registration exactly as it fired on the failed attempts. It therefore cannot be evidence of machine-level database corruption, and I withdraw that interpretation as the explanation for the unlaunchable state.

4. Five of six same-day registration attempts for this package failed, with no distinguishing logged error. One succeeded, five failed, and the deployment log records nothing that differentiates them. With database corruption ruled out, that pattern is the open question, and it sharpens the two standing asks in this issue: the updater's register-while-running behavior and the registration path are where the answer has to be.

Nothing else in the previous comment changes.

mrsoone · 21 days ago

Traced to the exact check: 0x3CFC refusal originates in the StateRepository registry cache, and every read succeeds

Windows 11 Home 26200.8973 (25H2), Claude Desktop 1.26832.0.0, sideloaded MSIX, Developer-signed.

Seven reproductions between 2026-07-24 and 2026-08-09. The crash is now reproducible on demand, so I detonated it deliberately under a full Process Monitor trace. Findings below are from that capture, not from inference.

The failing operation, caught 6 ms before the error

At the instant of the first AppModel-Runtime Event 6 0x3CFC ("error encountered while checking the machine-level package status", ErrorCode 15612), the Electron main process is reading the package status out of the StateRepository registry cache:

21:32:30.8228  RegOpenKey    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModel\StateRepository\Cache            SUCCESS
21:32:30.8229  RegSetInfoKey HKLM\...\StateRepository\Cache                                                          SUCCESS
21:32:30.8230  RegQueryValue HKLM\...\StateRepository\Cache\Metadata\Revision                                        SUCCESS
21:32:30.8230  RegOpenKey    HKLM\...\Cache\User\Index\UserSid\S-1-5-21-...                                          SUCCESS
21:32:30.8231  RegOpenKey    HKLM\...\Cache\PackageUserStatus\Index\UserAndPackageFullName                           SUCCESS
21:32:30.8233  RegOpenKey    HKLM\...\Cache\Package\Index\PackageFullName\Claude_1.26832.0.0_x64__pzs8sxrjxfjjc       SUCCESS
21:32:30.829   Event 6 0x3CFC  (x5, through .845)

Every operation returns SUCCESS. Nothing fails at the registry or file layer. The refusal is decided above it.

Two things this rules out:

  • It is the registry projection, not the SQLite store. The hot path is HKLM\...\AppModel\StateRepository\Cache\*, not C:\ProgramData\Microsoft\Windows\AppRepository\*.srd.
  • It is not access-denied or a missing key. Every read succeeded and returned data.

The GPU process exits cleanly. The refused restart is the actual fault.

This has been mis-framed as a GPU crash for seven incidents, including by me. The trace shows the GPU process (PID 26648) performing an orderly shutdown: a long, well-formed sequence of RegCloseKey / CloseFile / IRP_MJ_CLOSE, releasing icudtl.dat, mswsock.dll.mui, DirectXApps.sdb, the StateRepository cache keys, then vk_swiftshader.dll, then claude.exe itself.

A faulting process does not close its handles in order. Electron logs reason: 'crashed' because the child vanished from its point of view, which is not the same thing.

Sequence: GPU process exits cleanly at .810 → main process checks package status at .8228 → Windows refuses process creation at .829 → app collapses, package flips to Modified, NeedsRemediation.

So the GPU exit is the trigger; the fault is that the runtime will not let the app respawn the child.

Zero failed CreateProcess at the kernel level

Across the entire 6-second window (439,157 events), not one Process Create operation returned anything other than SUCCESS. The 0x3CFC refusal never reaches the kernel process-creation callback that Process Monitor hooks. Windows rejects it earlier, in the user-mode AppModel runtime, on the strength of the status check above.

This is likely why previous investigations found nothing: they were looking for a failed CreateProcess that does not exist.

Exit code: 7 for 7

Every crash logs the identical GPU exit code:

GPU process gone: { type: 'GPU', reason: 'crashed', exitCode: 101457950, serviceName: 'GPU' }

101457950 = 0x60C201E, identical across all seven, spanning two app versions (1.24012.11.0 and 1.26832.0.0).

Trigger: preview creation in a heavy restored session, 2 to 27 second fuse

The fuse from preview creation to GPU exit has been 2, 5, 7 and 2 seconds across traced crashes. But the discriminator is not the preview itself:

| Bait | Servers live | Session | Turns | Transcript | Result |
|---|---|---|---|---|---|
| Fresh chat | 1 browser-preview | new | 2 | 0.21 MB / 90 lines | survived |
| Restored | 1 browser-preview | restored | 27 | 3.03 MB / 1378 lines | crashed |

Same preview class, same count of one, opposite outcome. A 14x larger transcript on the fatal one. All four traced fatal previews belong to the same heavy session. The fatal class is consistently the seeded Browser pane (tabId: seed, no externalUrl); artifact previews (html-preview with claude.ai/code/artifact/...) were live and harmless alongside crashes.

Caveat, disclosed: the control ran on a different model than the killer, so those two rows are not model-matched. Transcript size and session age are the stronger differences but the comparison is not clean.

Restoring the session index re-arms this automatically: WarmLifecycle per-session warming begins 17 seconds after launch with no user interaction, which is enough to detonate unattended.

Bug report: [gpu-recovery] threshold can never fire under this failure mode

Independent of the Windows fault, the app ships a GPU crash safety net that is unreachable here:

[gpu-recovery] previous session died with %d GPU process deaths, disabling hardware acceleration for this launch

It triggers at 3 or more GPU deaths, tracked via a startup marker. This app dies at its first GPU death every time, so the counter never reaches 2. Across all seven crashes, main.log contains zero [gpu-recovery] lines. The net has never fired and, as calibrated, cannot.

Suggested fix: trigger auto-disable on the first GPU death followed by process termination, or persist the count across sessions rather than requiring three within one.

Worth noting it would not have saved this machine anyway: isHardwareAccelerationDisabled: true was verified in effect (vk_swiftshader.dll loaded in the GPU process, so software rendering was active) and the GPU process still existed and still exited. app.disableHardwareAcceleration() disables GPU compositing; it does not remove the process.

Also worth fixing

  • autoVerify in <cwd>\.claude\launch.json no longer gates the crashing paths in 1.26832.0.0. It is consulted only for launch tooling when the "Claude Browser" MCP server is present. createBrowserPreview and the artifact render path have no gate at all. This was an effective mitigation on 1.24012.11.0 and silently stopped working after the update.
  • App data path moved from %LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude to the unpackaged %APPDATA%\Claude, and the tree now survives package removal. Worth documenting.
  • A malformed claude_desktop_config.json is silently overwritten with defaults, discarding user keys. A UTF-8 BOM is enough to trigger it. A backup or a visible error would be better than silent data loss.

What I have

Full Process Monitor capture (6.44 GB), both /Debug tripwire channels, main.log, Crashpad dumps, and event logs at millisecond resolution for all seven incidents. Happy to provide any of it.

Open question for the team

Since every registry read in the status check succeeds, the failure is in the evaluation, not the retrieval. If anyone can say what PackageUserStatus evaluation would reject a package whose registry projection reads clean, that is the last gap. From outside, the remaining rungs look like an in-place Windows repair install or a clean install, neither of which is an app-side fix.

mrsoone · 20 days ago

Update: an in-place Windows repair install does not fix this. Crash 8 reproduced on the first deliberate trigger with the identical signature, 2.6 seconds after the preview was created.

Following up on my previous comment with the result of the decisive test.

The test. Windows 11 Home 25H2, build 26200.8973, fully patched. I ran Settings > System > Recovery > "Fix problems using Windows Update" (the in-place repair install). Verified afterwards that it genuinely reinstalled the OS: install date rewritten, Windows.old created, and the component store re-laid. Build, UBR, and servicing stack version (10.0.26100.8962) are all identical before and after, confirmed against Windows.old, so this was a clean reinstall of identical bits, which is the strongest servicing action available on a fully patched machine. The Claude package (1.26832.0.0, sideloaded MSIX) survived with Status Ok. Then, watched live at 3-second polling: opened a restored session and triggered one in-app browser preview.

The result, timestamped (2026-08-10, local):

| Time | Event |
|---|---|
| 07:03:56.430 | main.log: [Preview] Created browser preview, serverId browser-preview-1786370636430-0, tabId: seed, no externalUrl |
| 07:03:59.042 to .068 | Five Event 6 in Microsoft-Windows-AppModel-Runtime/Admin, error 0x3CFC: "Cannot create the process for package <NULL> because an error was encountered while checking the machine-level package status" |
| 07:03:59 | main.log: GPU process gone: { reason: 'crashed', exitCode: 101457950 }. This is the 8th consecutive occurrence with this exact exit code since 2026-07-28 |
| 07:04:00.684 | Get-AppxPackage Status flips from Ok to Modified, NeedsRemediation |
| 07:04:00.690 | Main process gone. App unlaunchable until removal and reinstall |

The user-visible mechanism, from the app's own tool output. In the session that dies, every turn that touches the preview shows preview_start returning the SAME serverId (preview-local_2b39e339-...) with reused: false, and the very next turn reports "No preview is open". So the preview pane is not persisting across turns: it is torn down and recreated on every turn, and each recreation is another GPU-child kill-and-respawn cycle running against the AppModel machine-level status check. The specific sequence that lands the kill, identical in crashes 7 and 8, is a resize_window call (mobile viewport) on the preview immediately after preview_start. The teardown-respawn churn is the weapon; the resize immediately after spawn is the trigger that fires it. Precise repro on this machine, eight for eight: in a session with preview history, let the assistant call preview_start, then a mobile-viewport resize_window on the pane it returns; the GPU child dies within 2 to 7 seconds and the package wedges.

Internals, from static analysis of the 1.26832.0.0 bundle (offered in case it helps):

  • The reused flag in the url-attach return is hardcoded: the path returns {serverId:c, port:e.port, name:e.name, reused:!1, ...} even when loadBrowserPreview found and reused the existing record, which is why the transcript shows the same serverId with reused: false on every turn.
  • A 5-minute reaper destroys hidden preview views ([Preview] Reaped hidden preview view, Mr=5*6e4), and the next tool call rebuilds a fresh GPU-backed WebContentsView. That teardown-rebuild cycle is the churn the GPU child is subjected to.
  • In our logs, only Created browser preview (browser-preview-*) ever precedes GPU death. html-preview-* artifact panes were created three times on 08-09 with no crash. The fatal class is specifically the browser preview.
  • Workarounds that hold from outside, verified in the code and now deployed on this machine, documented here for other affected users: "preferences": {"launchEnabled": false} in claude_desktop_config.json (the Claude Browser tool server's isEnabled gate reads it; the server never registers, so preview_start does not exist in sessions), a permissions.deny rule on mcp__Claude_Browser in user settings (enforced even under bypassPermissions), and managed disableBrowserExternalNavigation: true (latches PreviewPolicy off, fail-closed, covering the UI paths). These are workarounds, not a fix.

What is now excluded, cumulatively:

  • The OS servicing state of this machine (identical bits freshly re-laid; crash anyway).
  • Cold boot, user-scope Repair, Reset, and re-register (all "succeed" at user scope; the failing check is machine scope).
  • disableHardwareAcceleration / isHardwareAccelerationDisabled. This does NOT prevent it. With the flag verified on (byte-verified config, vk_swiftshader software rendering active), Chromium still spawns a --type=gpu-process child, and that process still dies. Crashes 7 and 8 both happened with the flag on. Note for anyone verifying: the flag shrinks the GPU process below the top-5 cutoff of the [process-memory] log line, so its absence from that line is a false negative. Enumerate real processes instead.
  • StateRepository corruption. Both databases pass integrity_check, and a full ProcMon trace across a kill (439,157 events) shows every read of the StateRepository registry cache returning SUCCESS at the moment of the first 0x3CFC. Zero failed Process Create operations reach the kernel. The refusal happens inside the user-mode AppModel runtime.
  • Deployment-layer involvement at kill time: with Microsoft-Windows-AppXDeploymentServer/Debug and Microsoft-Windows-StateRepository/Debug both enabled during the reproduction, neither logged a single event in the crash window.

Where this leaves it. The trigger is the Electron GPU process exiting (cleanly, per ProcMon) right after a browser preview is created; the fault is Windows then refusing to recreate the app's processes on a machine-level package status check that no observable state explains, permanently flipping the package to Modified, NeedsRemediation. I am filing the Windows side of this with Microsoft via Feedback Hub. On the app side, the question I cannot answer from outside: what does the GPU-process respawn path do differently from normal process creation that trips the AppModel machine-level status check, and can the preview feature avoid killing and respawning the GPU process on this path?

Full forensics retained (ProcMon PMLs, evtx exports, main.log snapshots) and available on request. Repro is 8 for 8 and takes under 10 seconds from trigger.