[BUG] macOS auto-update fails silently

Status Closed — not planned
Maintainer reply None cached
Activity 1 comment · opened Sep 4, 2026 · closed Sep 7, 2026

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?

Title: macOS auto-update fails silently in a launchd respawn loop after manual reinstall of a previously root-installed app (xpcproxy EACCES on root-owned ShipIt log files)

Environment

  • Claude Desktop 1.44121.4 (0d57a2), failing to update to 1.46388.2
  • macOS 15 (build 25G83), Apple Silicon, MDM-managed Mac (Mosyle); no MDM restriction on background items found (profiles show returned nothing relevant)
  • Single admin user, Claude.app in /Applications

Symptoms

  • Persistent in-app banner "Update didn't complete — Please quit and reopen Claude" for roughly one month, on every launch.
  • Quitting and reopening never applied the update. Deleting Claude.app and reinstalling from the public DMG did not help (DMG shipped 1.44121.4; updater kept targeting 1.46388.2).
  • Squirrel ShipIt log in ~/Library/Caches/com.anthropic.claudefordesktop.ShipIt/ stopped receiving any entries, despite the app logging successful downloads every day.

What Should Happen?

Suggested fixes

  • Before submitting the ShipIt launchd job, check that the stdout/stderr log paths are writable by the submitting identity; if not, rotate to a new file name or remove/recreate them.
  • Detect a job that repeatedly exits with 78 / never produces log output and surface a specific error ("updater could not start — permission problem in <path>") instead of the generic banner.
  • Consider a bounded retry/backoff on the launchd job rather than an unbounded 2-second respawn.
  • On reinstall or on ownership change of the app bundle, clean or reset the ShipIt cache directory.

Error Messages/Logs

App-side log (~/Library/Logs/Claude/main.log)
- [updater] Update downloaded and ready to install { releaseName: 'Claude 1.46388.2' }
- [updater] Previous update install did not apply (still at 1.44121.4, attempted Claude 1.46388.2 …)
- [updater] Install of 1.46388.2 has failed to apply 1 time(s) at this version
- config.json: updaterFailedInstall { appVersion: 1.44121.4, targetVersion: 1.46388.2, attempts: 2 }
- ShipItState.plist was valid and update.<id>/Claude.app was present and complete.

Root cause (verified)
- `launchctl print gui/xxx/com.anthropic.claudefordesktop.ShipIt` showed: state = spawn scheduled, runs = 6304, last exit code = 78 (EX_CONFIG), stderr path = …/ShipIt_stderr.log.100.
- Unified log for launchd: `initialization failure: 25G83: xpcproxy … : 0xd` followed by `xpcproxy exited due to exit(78)`, `ran for 15ms`, respawn every 2 seconds. 0xd = EACCES.
- All ~200 ShipIt_stdout.log*/ShipIt_stderr.log* files in the ShipIt cache directory were owned by root:staff with mode 644, while the directory, ShipItState.plist and the staged update were owned by the user.
- The app had originally been installed/updated with a root-privileged ShipIt (logs owned by root since June 2025). After the user deleted Claude.app and reinstalled by drag-and-drop, /Applications/Claude.app became user-owned, so the ShipIt job was submitted in the gui/<uid> domain. launchd (via xpcproxy) could not open the root-owned stdout/stderr files for the job and refused to spawn ShipIt at all. ShipIt never ran, so it never logged the failure.

Impact
- Update never applies; user sees a generic banner with no actionable information.
- launchd respawns the job every 2 seconds indefinitely (6,000+ spawn attempts in ~3.5 hours) as long as the app is running — a background CPU/log drain.
- Reinstalling the app does not fix it; in this case it is what triggered the failure mode.
- Likely affects any user whose Claude.app was deployed via MDM or installed by an admin and later reinstalled manually, or whose app ownership changed for any other reason.

Steps to Reproduce

Workaround that resolved it

  1. Quit Claude.
  2. launchctl bootout gui/<uid>/com.anthropic.claudefordesktop.ShipIt
  3. Move the root-owned ShipIt_std.log files out of ~/Library/Caches/com.anthropic.claudefordesktop.ShipIt/ (directory is user-owned, so no sudo needed).
  4. Relaunch Claude. A fresh user-owned ShipIt_stderr.log appeared with "Detected this as an install request"; quit and relaunch installed 1.46388.2 successfully.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

Claude 1.46388.2 (cb4596) 2026-09-04T07:03:48.000Z

Platform

Other

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗