Skip to content

Explain why the privileged helper couldn't be installed or reached - #866

Draft
anciltech wants to merge 3 commits into
XcodesOrg:mainfrom
anciltech:fix/helper-install-errors
Draft

anciltech wants to merge 3 commits into
XcodesOrg:mainfrom
anciltech:fix/helper-install-errors

Conversation

@anciltech

@anciltech anciltech commented Sep 29, 2026 •

Copy link
Copy Markdown

Summary

After consenting to install the privileged helper, users could get:

Installation was completed, but some post-install steps weren't performed automatically. Xcodes performs these steps with a privileged helper, which appears to not be installed.

with no indication of why. Three changes:

  • Keep the real reason. performPostInstallStepsAsync replaced every failure with this generic message. The underlying reason is now carried in postInstallStepsNotPerformed(..., reason:) and appended to the alert (not when the user simply declined).
  • Wait for a newly installed helper. SMJobBless returns before launchd has started the job, and the version check ran immediately once, so a slow start was reported as "not installed". The check now retries a few times (500 ms apart) and stops if the task is cancelled.
  • Say what went wrong. If the helper was installed but still can't be reached, throw HelperClientError.unreachableAfterInstall explaining the likely cause: the app and helper are signed by different teams (the helper's SMAuthorizedClients rejects the app, e.g. a local development build next to a helper installed by the released app). SMJobBless's kSMErrorInvalidSignature gets a similar explanation, and kSMErrorAuthorizationFailure (shown raw as "CFErrorDomainLaunchd.4" before) explains that macOS didn't authorize the install, e.g. the administrator prompt was cancelled.

New strings: HelperClient.error.AuthorizationFailed, HelperClient.error.InvalidSignature, HelperClient.error.UnreachableAfterInstall (English only for now).

Tests

  • test_InstallHelper_RetriesUntilNewlyInstalledHelperAnswers
  • test_InstallHelper_ThrowsWithReasonWhenInstalledHelperIsUnreachable
  • test_PostInstallStepsError_IncludesUnderlyingReason

🤖 Generated with Claude Code

anciltech and others added 3 commits September 29, 2026 16:26
Every post-install failure was reported as "the privileged helper
appears to not be installed", with no indication of the cause.

- Keep the underlying reason in postInstallStepsNotPerformed and show it
  in the alert (unless the user declined to install the helper).
- SMJobBless returns before launchd starts the helper, and the version
  check ran once right away, so a slow start looked like a failed
  install. Retry the check a few times, stopping if cancelled.
- If the helper still can't be reached after installing, say so and
  name the likely cause: the app and helper are signed by different
  teams (e.g. a local build next to a helper from the released app).
  SMJobBless's invalid-signature error gets a similar explanation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CFErrorDomainLaunchd error 4 (kSMErrorAuthorizationFailure) was shown
raw as "The operation couldn't be completed. (CFErrorDomainLaunchd.4)".
It means macOS didn't authorize the install, e.g. the administrator
prompt was cancelled, so say that and how to retry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Compare against the launchd error domain string instead of the
  deprecated kSMErrorDomainLaunchd constant.
- Mark the helper error strings as manually managed in the string
  catalog, like the other keys only used through localizeString, so
  Xcode doesn't flag them as stale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant