[BUG] Claude Desktop (macOS): instances quit silently — clean beforeQuit, no crash report, not memory, active window always survives
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
NOTE: This is a Claude Desktop bug, not Claude Code CLI. Filing here per the guidance that Desktop issues belong in this repo with the external label.
I run multiple Claude Desktop windows as my normal workflow (3-4 at a time). Windows quit themselves with no error, no crash dialog and no warning — the window simply disappears.
The consistent pattern: it is almost always a window I am NOT actively typing in. The window with focus survives; idle ones die. 17 quit events in a single day.
Environment:
- Claude Desktop 1.24012.9
- macOS 26.5 (25F71)
- MacBook Pro M3 Pro, 18GB RAM
Instance lifetimes are inconsistent, so it does not appear to be a fixed timer:
launched 17:47 -> quit 17:51 (~3.5 min)
launched 18:00 -> quit 18:03 (~2.5 min)
launched 18:04 -> quit 18:20 (~16 min)
What Should Happen?
Instances should stay open until the user closes them.
If the app is deliberately terminating an instance, the reason should be logged. At present main.log records a full graceful shutdown with no preceding entry indicating any trigger, which makes this impossible to diagnose or work around.
Error Messages/Logs
Every quit is a clean, deliberate shutdown — not a crash:
18:23:54 [info] Successfully run onQuitCleanup: cowork-vm-shutdown
18:23:54 [info] Successully ran all onQuitCleanup handlers, marking readyForQuit
18:23:54 [info] beforeQuit: handler fired, going down
18:23:54 [info] beforeQuit: handler is ready for quit, so quitting
18:23:54 [info] [EventLogging] Flushing 1 events
18:23:54 [info] willQuit: handler fired, going down
18:23:54 [info] willQuit: handler is ready for quit, so quitting
All cleanup handlers run, exit code 0. Nothing is logged in the 20+ seconds beforehand — no error, no warning, no trigger. Silence, then shutdown.
Memory reading from the app's own telemetry at the last quit:
tree_rss_sum=1286MB sys_free=... sys_free_raw=1784MB
1.7GB genuinely free, zero swap in use.
Also seen with multiple instances open:
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 listeners added to [EventEmitter]
...claude.settings_$_AppPreferences
...claude.web_$_AutoUpdater_$_updaterState
...claude.web_$_LocalAgentModeSessions
Steps to Reproduce
- Open Claude Desktop normally
- Open additional instances from Terminal:
open -n -a Claude(repeat for 3-4 total) - Work in one window and leave the others idle
- Within a few minutes one or more idle windows quits itself, with no warning or error shown
- Check
~/Library/Logs/Claude/main.log— a cleanbeforeQuit/willQuit/onQuitCleanupsequence with exit code 0 - Check
~/Library/Logs/DiagnosticReports— no crash report and no jetsam report exists - Check
~/Library/Application Support/Claude/Crashpad/pending— empty
Happens on a fresh boot with several GB free and zero swap in use.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude Desktop 1.24012.9 (CCD 2.1.219) — not Claude Code CLI
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
What I ruled out
- Not a crash. Zero entries in
~/Library/Logs/DiagnosticReports. Crashpadpendingfolder empty. - Not an OOM kill. No jetsam reports. Last quit occurred with 1.7GB free and zero swap.
- Not general memory pressure. Removed ~2GB of other apps and rebooted after 33 days uptime. Swap went to zero, wired memory dropped from 2.97GB to 1.76GB. Quits continued.
- Not a stale bridge session. Found
bridge-state.jsonpinning a deadremoteSessionId, retrying and failing 68 times in 45 minutes (Transport permanently closed code=4090,AcknowledgeWork: Conflict (409): Work item must be in QUEUED state). Deleting the file took transport failures to zero and instances survived noticeably longer — but quits still occur. - Not user-initiated. Individual windows die while others stay open, so a global quit action cannot explain it.
- Not a modified install. Single
Claude.app, signed by Anthropic (TeamIdentifier Q6L2SF6YDW).
Related observations
[WarmLifecycle:cowork] Initialized (arm=always)fires on every launch. The Cowork VM starts whether or not Cowork is used, sits at 1.1-1.9GB and grows through the day. There is no user-facing way to disable it on an individual plan — the only toggle is org-level (Team/Enterprise).trigger=stallfires on every newly launched instance.- All instances write to a single shared
main.log, which makes attributing a quit to a specific instance impossible.
Requests
- Log the reason an instance quits — there is currently nothing actionable.
- Provide a way to disable the Cowork VM on individual plans for users who don't use Cowork.
- Clarify whether multiple instances are a supported configuration.
Possibly related but not a duplicate: #23092 (SessionIdleManager 300s idle quit). I checked — SessionIdleManager, lam_vm_shutdown_completed and was_killed do not appear anywhere in my logs, and my instance lifetimes are inconsistent rather than a fixed 300s. Likely a different mechanism.
Happy to provide the full main.log on request.
3 Comments
Additional context on the regression question.
This began after Cowork was integrated into the main desktop app. Before that I ran 3-4 instances routinely as my standard workflow with no instability at all. I can't pin an exact version number, but the change in behaviour tracks with that integration rather than with any change on my machine.
claude-main.log
Two things that may help narrow it down:
The Cowork VM is armed on every launch regardless of use.
[WarmLifecycle:cowork] Initialized (arm=always)appears at every startup. I have never opened Cowork in these sessions. The VM process sits at 1.1-1.9GB and grows over the course of a day. With no way to disable it on an individual plan, every extra instance carries that cost whether the feature is wanted or not.Instances that stay focused survive indefinitely. One instance in my logs ran for over three hours without issue while others launched alongside it died within minutes. That asymmetry seems like the most useful clue — whatever terminates them appears to discriminate by activity or focus, but nothing in
main.logrecords the decision.Happy to run any diagnostic that would help, or to provide the full log for the day (13:03-18:30, 17 quit events).
Useful for anyone else debugging this:
DESKTOP_LOG_LEVEL=debugunlocks far more diagnostic outputFrom
index.chunk-CnWKsyE_.js:Launching the binary directly with the variable set turns on debug logging in packaged builds:
This adds several hundred debug lines to
main.log, including a full dump of every GrowthBook feature gate with its resolved state (466 gates in my case, in the form[growthbook] <id>: on=true|false value=... source=...). That makes it possible to check whether a given feature is actually enabled for your account rather than guessing.A candidate I was able to rule out with it:
app.asarcontains a stealth auto-update scheduler (scheduleRestartWhenIdle, class withconst w7e=600*1e3) whose logic matches this bug's symptom closely —idleBlocker()returns"window focused"andreportWindowFocus()cancels the countdown, so a focused window would never be restarted while blurred ones would be quit and reinstalled after 10 minutes. There is also a[stealth-relaunch]path that saves navigation history to a marker file beforeapp.quit().It is gated behind
3691521536. With debug logging on, my dump shows:So stealth update is not the cause here — at least not for my account. Recording it so nobody else spends time on the same lead.
Suggestion for the app: whatever terminates an instance should log the reason at
infolevel.main.logcurrently records a completebeforeQuit→onQuitCleanup→willQuitsequence with no preceding entry explaining the trigger, which makes this effectively undiagnosable from the outside. A single line naming the caller would have resolved this in seconds.I now have an instance running with
DESKTOP_LOG_LEVEL=debugand will post the debug output from the next quit.Update after 24 hours of monitoring — this looks like singleton contention between instances, not resources. Reproducible at exactly the third instance.
I ran a monitor overnight sampling every 2 minutes. New findings:
Memory is conclusively ruled out
Two instances ran continuously for 13h50m and 13h43m overnight. During that window
sys_free_rawrepeatedly dipped as low as 70MB (samples at 0.07GB, 0.10GB, 0.11GB, 0.13GB). Neither instance quit. If low memory triggered these quits, they would have died many times over.The failure is deterministic at the third instance
Two instances: stable indefinitely. Launch a third and something quits within ~10 seconds:
Memory at those quits:
sys_free_raw=766MBandsys_free_raw=272MB. Not exhaustion.What the third instance's startup actually does
This is the part that looks like the bug. During the third instance's initialisation:
So a newly launching instance:
[ScheduledTasks] Already initialized— a shared service it cannot claimThen, seconds later, an instance quits.
Together with the previously reported
MaxListenersExceededWarning: 11 listenersonAppPreferences,AutoUpdater updaterStateandLocalAgentModeSessions, and the fact that all instances write to one sharedmain.log, the picture is that session state, scheduled tasks and the Cowork VM are effectively process-global singletons. Two instances tolerate sharing them. A third cannot initialise without tearing down state the others depend on, and one of them exits.This would explain why the quit is always graceful with no logged reason — from the quitting instance's perspective nothing failed. It would also explain why this began when Cowork was integrated, since the shared VM and the session manager arrived with it.
Useful diagnostic for anyone reproducing this
DESKTOP_LOG_LEVELis read at startup and overrides the packaged default ofinfo:That adds several hundred debug lines including a full dump of every GrowthBook gate with its resolved state (466 in my case), which is how I eliminated one candidate:
app.asarcontains a stealth restart scheduler (scheduleRestartWhenIdle, 600s idle timeout, cancels on window focus) that matches the symptom well, but its gate readson=falsefor my account, so it is not the cause here.Also ruled out since the original report
_kLSApplicationWouldBeTerminatedByTALKey=1events occur after the quit begins, so they are a consequence of teardown, not the trigger.Suggested fix direction
Either make
ScheduledTasks,LocalAgentModeSessionManagerand the Cowork warm VM safe for N instances, or have a launching instance detect existing instances and skip re-initialising shared services rather than resetting them. Failing that, a clear statement that multiple instances are unsupported would at least let users stop at two deliberately.Happy to provide the overnight monitor log or run any further diagnostic.