Skip to content

Sparkle auto-update fails on macOS (non-sandboxed): SUSparkleErrorDomain(4005) / Timeout: agent connection was never initiated #5123

@nhodges

Description

@nhodges

cmux version

0.64.9

macOS version

macOS 26.4.1

Mac chip

Apple Silicon (M1/M2/M3/M4)

Installation method

Direct download (DMG)

Can you reproduce this on cmux NIGHTLY?

I could not test NIGHTLY

Bug description

Summary

Auto-update in cmux v0.64.9 fails on macOS with Sparkle error 4005 (underlying error 10, "agent connection was never initiated"). The update downloads and
verifies (EdDSA signature OK), but the install handoff to Sparkle's Installer XPC times out, so no version ever gets installed. Manually replacing
/Applications/cmux.app with the latest .dmg works, so the published artifact is fine — the issue is in how Sparkle is bundled.

Environment

  • cmux: v0.64.9 (also reproduces with the published v0.64.11 download flow — same bundle layout)
  • macOS: 15.x (Darwin 25.4.0)
  • Sparkle: 2.8.1, embedded in cmux.app/Contents/Frameworks/Sparkle.framework/
  • App signing: notarized Developer ID, team 7WLXT3NR37, matches across cmux, Autoupdate, Updater.app, and Installer.xpc — not a Team ID mismatch.

Symptom in the UI

Message: An error occurred while running the updater. Please try again later.
Domain: SUSparkleErrorDomain
Code: 4005
Failure: The remote port connection was invalidated from the updater...
Debug: SUSparkleErrorDomain(4005) | ... | underlying=SUSparkleErrorDomain(10) Timeout: agent connection was never initiated

The error text suggests sandboxing entitlements, but the app isn't sandboxed — see Root Cause below.

Root cause

cmux.app ships the Sparkle helper XPC services intended for sandboxed apps:

cmux.app/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices/
├── Downloader.xpc
└── Installer.xpc (CFBundleIdentifier = org.sparkle-project.InstallerLauncher)

But cmux.app is not sandboxed (codesign -d --entitlements - on the main exec returns no com.apple.security.app-sandbox key), and:

  • Installer.xpc has no entitlements at all (codesign -d --entitlements - on it returns the executable path with no entitlements blob).
  • The main app has no com.apple.security.temporary-exception.mach-register.com.cmuxterm.app-spki / -spkp / -spks exceptions.

When Autoupdate runs, it sets up Mach service listeners on com.cmuxterm.app-spki (Installer Connection) and com.cmuxterm.app-spkp (Installer Launcher) and then
waits for Installer.xpc to call back. Installer.xpc launches but cannot reach those Mach services — Sparkle's Updater.app logs the symptom directly:

Updater: activating connection: mach=true ... name=com.cmuxterm.app-spkp
Updater: failed to do a bootstrap look-up: xpc_error=[3: No such process]
Updater: [Sparkle] Agent failed..
Updater: [Sparkle] Error: Agent Invalidating without having the chance to reply to installer
Autoupdate: [Sparkle] Error: Timeout: agent connection was never initiated

Per Sparkle's sandboxing docs, the XPC services should either be removed for non-sandboxed apps (Sparkle uses an in-process installer instead) or kept with the
matching Mach-register temporary-exception entitlements + XPCService.JoinExistingSession / application-groups wired up correctly. cmux ships them with neither,
which is the configuration that produces this specific timeout.

Fix (recommended)

In the macOS build pipeline, delete Sparkle.framework/Versions/B/XPCServices/ (both Installer.xpc and Downloader.xpc) before code-signing the framework and the
app. Sparkle falls back to the in-process installer path for non-sandboxed apps, which is the supported configuration. Make sure to re-sign the framework after
removal so the seal stays valid:

inside the build, after Sparkle is copied into the app bundle, before signing

rm -rf "/Contents/Frameworks/Sparkle.framework/Versions/B/XPCServices"
codesign --force --options runtime --timestamp
--sign "Developer ID Application: Manaflow, Inc. (7WLXT3NR37)"
"/Contents/Frameworks/Sparkle.framework/Versions/B"

then sign the rest of the app as usual

Alternative: keep the XPC services and add the documented Mach-register entitlements + plist wiring. Simpler to just drop them since cmux isn't sandboxed.

How to reproduce

  1. Install cmux v0.64.9.
  2. Use the in-app "Check for Updates" against the published appcast at https://github.com/manaflow-ai/cmux/releases/latest/download/appcast.xml.
  3. Update downloads and verifies, then fails with the 4005 error above.
  4. Tail ~/Library/Logs/cmux-update.log and log show --predicate 'process == "Autoupdate" OR process == "Updater"' to see the bootstrap-lookup failure.

Workaround for affected users

Download the latest cmux-macos.dmg from Releases and drop the new cmux.app over /Applications/cmux.app. Future updates will keep failing until the build change
above ships

Expected behavior

I should be able to update through the cmux app

Steps to reproduce

How to reproduce

  1. Install cmux v0.64.9.
  2. Use the in-app "Check for Updates" against the published appcast at https://github.com/manaflow-ai/cmux/releases/latest/download/appcast.xml.
  3. Update downloads and verifies, then fails with the 4005 error above.
  4. Tail ~/Library/Logs/cmux-update.log and log show --predicate 'process == "Autoupdate" OR process == "Updater"' to see the bootstrap-lookup failure.

Shell and environment

No response

Relevant logs or crash reports


Screenshots or screen recordings

No response

Additional context

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions