Diagnostic Log · Windows / MSIX

Where the Update Stalls:
When Claude Desktop Says “the executable is in use”

You restart the app to update it, the installer complains that the executable is in use, and then the app won’t launch at all — even though every process is already dead. The culprit isn’t a process. It’s a zombie Job object that outlived its process.

Topic · MSIX package update lock Environment · Windows 10/11 · Claude Desktop Level · Intermediate · PowerShell required
svchost.exe pid 8116 · container host ZOMBIE JOB Claude 1.15962 old version · no process SWITCH BLOCKED READY · BLOCKED Claude 1.17377 new version · waiting handle.exe · svchost.exe pid:8116 type:Job -> Container_Claude_1.15962.1.0

The conclusion first. If a Claude Desktop update stalls on “the executable is already in use” and the app then refuses to launch, the app process is usually already gone. What’s holding you back isn’t a process — it’s the Job object of the old MSIX container, left as a zombie under svchost.exe. Miss this, and no amount of killing processes in Task Manager — or reinstalling the app — will stop the loop.

This is a record of running into that symptom and pinning down its cause. Before you make things worse with a hasty reinstall or a force-kill, here is what to check and what to leave alone, in order.

/ 01 — SYMPTOM

You hit update, and the app vanished

The pattern goes like this. You restart the app to apply an update. During install, a warning says the executable is in use and the update never finishes. Then, when you try to open the app again, it won’t even start.

Here’s the step most people take instinctively: open Task Manager, end every process with Claude in its name, and launch again. And the symptom is still there. Keep suspecting a process at this point and you’ll get nowhere, because a process is no longer the cause.

Caution

This happens during the update handover stage of an MSIX (Windows Store–style) package app. The old version has to come down completely before the new one takes its place, and that final lock hasn’t released. Reinstalling first means writing over a half-applied package state, which only makes the cause harder to see.

/ 02 — MISDIAGNOSIS

The process list is empty, yet it’s locked

To be sure, stop guessing and look at the actual state. In an elevated PowerShell, check two things: which Claude processes are alive, and what holds a handle on the files and objects. For handles, use Sysinternals handle.exe — it surfaces kernel objects more precisely than Task Manager or Resource Monitor.

# Live Claude processes (the app itself)
Get-Process *claude* | Select ProcessName, Id, Path

# What is holding what
handle.exe -a claude

Check · elevated PowerShell

And here comes the decisive frame. Get-Process returned nothing — the app itself is already dead. Yet the top line of handle.exe was still alive:

svchost.exe  pid: 8116  type: Job  710: \Container_Claude_1.15962.1.0_x64__pzs8sxrjxfjjc-...

Evidence · the old-version Job gone zombie

Not a file handle — a Job object. An MSIX app runs inside a per-container Job object, and while that Job is alive, the deployment engine refuses to replace the package’s files. That’s why you see “the executable is in use.” The thing holding on was never the visible app window; it was a Job in the kernel.

Reading handle.exe output strip the noise and the signal is one line msedge.exe · chrome.exe -> https_claude.ai_0.indexeddbbrowser web session · unrelated to the appNOISE python.exe xN -> .claude/worktrees/… (task runners)outside the sandbox · keep · do not killKEEP svchost.exe pid:8116 type:Job -> Container_Claude_1.15962old-version Job · lingers with no process · the real lockSIGNAL Narrow to container members with a filter Get-Process | ? { $_.Path -like “*WindowsApps*Claude*” }

Discard three kinds of noise first. The browser’s claude.ai IndexedDB handles are just web sessions, unrelated to the app; the task runners in the worktrees live outside the MSIX sandbox and have nothing to do with the lock. The one line that remains — the old-version Job — is the real cause.

Do not touch

Do not kill svchost.exe (pid 8116) directly. It hosts multiple services, and ending it carelessly takes unrelated services down with it. Your target is not svchost itself but the app process inside it that’s holding the container.

/ 03 — PINPOINT

The clue: the versions don’t match

Narrow it with a WindowsApps*Claude* filter and exactly one surviving app process appears. And that’s where the nature of the incident is settled.

Get-Process | ? { $_.Path -like "*WindowsApps*Claude*" } | Select ProcessName, Id, Path

ProcessName   Id   Path
-----------   --   ----
cowork-svc  4408   …\Claude_1.17377.1.0_x64__…\resources\cowork-svc.exe

Pinpoint · the single process holding the lock

The versions are crossed. The zombie Job is old version 1.15962, while the surviving process is cowork-svc.exe from the new version 1.17377 folder. The update already laid down the new package, but the old container couldn’t come down, so the handover never completed. This one background service was the last lock.

/ 04 — RELEASE

In order — but the last rung is a reboot

With the holding process pinpointed, bring it down first. cowork-svc restarts automatically when you reopen the app, so there’s nothing to lose by ending it now.

Stop-Process -Id 4408 -Force

# Check 1: is the Claude process gone?  -> empty output is correct
Get-Process | ? { $_.Path -like "*WindowsApps*Claude*" }

# Check 2: has the old-version Job disappeared?
handle.exe -a Container_Claude

Release attempt · step 1

Here it forks two ways. If you’re lucky, the Job disappears with the process and you’re done. But in this case, even after every process was down, the old-version Job stayed. A Job object had lodged in the kernel as a zombie with no process to hold it. That state is beyond the reach of Stop-Process.

Before moving to a reboot, you can try restarting the deployment-related services to coax the zombie Job into cleanup.

Restart-Service AppXSvc -Force -ErrorAction SilentlyContinue
Get-Service ClipSVC, AppXSvc, StateRepository | Restart-Service -Force -ErrorAction SilentlyContinue

# Re-register the new version to force the handover
Get-AppxPackage *Claude* | Foreach {
  Add-AppxPackage -DisableDevelopmentMode -Register "$($_.InstallLocation)\AppXManifest.xml"
}

handle.exe -a Container_Claude   # check again

Release attempt · steps 2–3

In this case, even a service restart and re-registration failed to release the Job. A zombie Job that survives process termination, service restart, and re-registration comes down, in the end, only with a reboot.

The release ladder the first three are attempts; the last one settles it 1 Stop-Process · end cowork-svcJob remains 2 Restart-Service · restart AppXSvcJob remains 3 Add-AppxPackage · re-register new versionJob remains 4 Reboot · force-release the zombie Jobreleased

A reboot here isn’t a shortcut that skips diagnosis. It’s the last physical resort left after you’ve pinpointed the lock as a zombie Job and exhausted process termination, service restart, and re-registration. Because the order was followed, the reboot is a justified conclusion.

Safe to rely on

What a reboot costs has nothing to do with the app. Your local Git repositories, your commits, and anything already written to disk are all intact. The only thing at risk is temporary output still being written at the moment of reboot. Just commit or stash the changes of any in-flight work beforehand.

After the reboot, check once more. If the zombie Job is gone, the switch to the new-version container completed cleanly and the app launches normally.

handle.exe -a Container_Claude
# if no 1.15962 line appears, you're done

Check · after the reboot


For the reader — points to watch

If you hit the same symptom, these four things are worth keeping in mind so you don’t make it worse.

01

An empty process list doesn’t mean the lock is released

Even if Claude isn’t visible in Task Manager, a Job object may still be in the kernel. Judge only after confirming the real lock holder with handle.exe — not the visible window.

02

Don’t make reinstalling your first move

Layering a reinstall over a half-applied update only clouds the cause. Walk the order — end process, restart services, re-register, reboot — and keep reinstalling as the last resort after that.

03

Leave unrelated work processes and browser handles alone

The diagnostic output mixes in claude.ai web sessions and unrelated task runners. Kill everything with “claude” in the name and you’ll only lose healthy work. Narrow the lock target to processes under the WindowsApps path.

04

A reboot is valid as a conclusion after pinpointing, not as a surrender

A reboot thrown out without diagnosis is not the same as one after you’ve narrowed the cause to a zombie Job. Once you know what locked and why, a single post-reboot check lets you declare the matter closed.

In short — the common culprit behind an MSIX update stuck on “the executable is in use” is the old container’s zombie Job object. Don’t stop at killing processes; pinpoint the lock holder with handle.exe, then release it in order, and you’ll recover in most cases without reinstalling.

Diagnostic environment · Windows · Sysinternals Nthandle v5.0 · Claude Desktop MSIX 1.15962 -> 1.17377 handover · PIDs/versions are from the actual diagnostic session

Scroll to Top