Skip to content

fix: verify helper binary on disk after SMAppService registration#36

Merged
GeiserX merged 2 commits intomainfrom
fix/smappservice-verify-binary
Apr 22, 2026
Merged

fix: verify helper binary on disk after SMAppService registration#36
GeiserX merged 2 commits intomainfrom
fix/smappservice-verify-binary

Conversation

@GeiserX
Copy link
Copy Markdown
Owner

@GeiserX GeiserX commented Apr 22, 2026

Summary

  • After SMAppService.register() reports success, verify the helper binary actually exists on disk at /Library/PrivilegedHelperTools/
  • If missing, automatically fall back to the legacy AppleScript install path (which does the actual file copy + launchctl bootstrap)
  • Observed with enterprise security tools like Zscaler that intercept daemon registration — SMAppService registers the service metadata but never places the binary

Fixes #35

Context

User reported helper connection failures on v2.5.0 (and v2.4.5). Diagnostics showed:

  • Helper binary not on disk (No such file or directory)
  • Launchd plist not on disk
  • But launchd had the service registered (SMAppService metadata)
  • Manual install via sudo cp + launchctl bootstrap worked immediately

Root cause: SMAppService.register() can succeed without placing the binary, especially when enterprise security software intercepts the operation.

Test plan

  • 68 unit tests pass
  • Build succeeds
  • Manual test: fresh install on clean system (no helper on disk) — should try SMAppService first, then verify
  • Confirmed by reporter: manual install workaround resolved the issue

Summary by CodeRabbit

  • Bug Fixes
    • Improved the helper tool installation process to better handle edge cases. The system now verifies that the tool is properly installed on disk after registration succeeds and automatically falls back to an alternative installation method if the tool is missing.

SMAppService.register() can report success without actually placing the
binary at /Library/PrivilegedHelperTools/. Observed with enterprise
security tools like Zscaler that intercept daemon registration. Now
checks the binary exists after registration and falls back to the
legacy AppleScript install path if missing.

Fixes #35
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Warning

Rate limit exceeded

@GeiserX has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 7 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 25 minutes and 7 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3ba050b0-cb54-4aeb-8ba2-aa1ee942b45b

📥 Commits

Reviewing files that changed from the base of the PR and between ee5470d and 8079724.

📒 Files selected for processing (1)
  • Sources/HelperManager.swift
📝 Walkthrough

Walkthrough

The change modifies the helper installation process to verify the helper binary exists on disk after SMAppService registration succeeds. If registration reports success but the binary is missing, the method now falls back to legacy installation instead of continuing.

Changes

Cohort / File(s) Summary
Helper Installation Verification
Sources/HelperManager.swift
Added on-disk existence check for the helper binary after SMAppService registration. If the binary is missing despite successful registration, the method falls back to installHelperLegacy(). Conditional error clearing adjusted to occur only after verification passes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately describes the main change: verifying helper binary exists on disk after SMAppService registration.
Description check ✅ Passed Description covers the change, context, and test status but is missing some checklist items like testing platforms and build verification.
Linked Issues check ✅ Passed Changes directly address issue #35 by implementing the binary existence verification and fallback mechanism to handle SMAppService registration failures caused by enterprise security tools.
Out of Scope Changes check ✅ Passed All changes are scoped to the helper installation logic in HelperManager.swift and directly support the objective of fixing issue #35.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/smappservice-verify-binary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/HelperManager.swift`:
- Around line 273-281: After SMAppService.register() returns success you
currently only check helperPath; change the logic to verify both the helper
binary and the launchd plist exist (use FileManager.default.fileExists(atPath:
helperPath) && FileManager.default.fileExists(atPath: launchdPlistPath)) before
clearing installationError and treating installation as successful; if either
file is missing, log a warning similar to the existing message and call return
installHelperLegacy() so behavior matches the validation in ensureHelperReady()
and prevents clearing installationError prematurely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0a7b1ead-f283-483d-b3c0-7965732942d0

📥 Commits

Reviewing files that changed from the base of the PR and between 434fb0c and ee5470d.

📒 Files selected for processing (1)
  • Sources/HelperManager.swift

Comment thread Sources/HelperManager.swift
@GeiserX GeiserX merged commit dd24ef5 into main Apr 22, 2026
3 checks passed
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.

[Bug]: Cannot connect to helper - helper could not be started

1 participant