Why Clicking “Open in GitHub Desktop” Opens the Wrong App — and How to Fix It

If you've ever clicked "Open with GitHub Desktop" on a GitHub repo page and watched the wrong app launch — SourceTree, Fork, or something else entirely — you're not alone. This is a macOS URL scheme handler conflict, and Apple gives you almost no tools to fix it through the UI.

Here's what happened to me on macOS Tahoe 26.3.1, how I diagnosed it, and how I fixed it from the command line. I'll also share some free tools that make this a one-liner in the future.

The Problem

On GitHub's website, when you click Code → Open with GitHub Desktop, the browser navigates to a special URL that looks like this:

x-github-client://openRepo/https://github.com/some-user/some-repo

This is a custom URL scheme — similar to how mailto: opens your email client or slack:// opens Slack. The x-github-client:// scheme is supposed to be handled by GitHub Desktop.

But on my Mac, clicking that link opened SourceTree instead. GitHub Desktop was installed and working fine when launched directly — the browser just wasn't sending the link to the right app.

This happened in both Safari and Brave. It wasn't a browser issue. It was a macOS issue.

Why This Happens

On macOS, when you install an app, it can declare in its Info.plist that it handles certain URL schemes. Both GitHub Desktop and SourceTree claim to handle x-github-client://. The last app to register with macOS LaunchServices tends to "win" — silently.

There's no popup asking you to choose. No preference pane to manage it. macOS System Settings only lets you change two default handlers: your web browser (http/https) and your email client (mailto). For every other URL scheme, you're on your own.

Diagnosing the Issue

Step 1: Test from the command line

Before touching anything, I tested whether the issue was browser-specific or system-wide:

open "x-github-client://openRepo/https://github.com/octocat/Hello-World"

This opened SourceTree, confirming the problem was at the macOS LaunchServices level, not the browser.

Step 2: Confirm the app bundle identifiers

Every macOS app has a unique bundle identifier. I needed to know the exact IDs for both apps:

mdls -name kMDItemCFBundleIdentifier "/Applications/GitHub Desktop.app"

Output: com.github.GitHubClient

mdls -name kMDItemCFBundleIdentifier "/Applications/Sourcetree.app"

Output: com.torusknot.SourceTreeNotMAS

Step 3: Check what URL schemes GitHub Desktop declares

To verify that GitHub Desktop should be handling this scheme:

/usr/libexec/PlistBuddy -c "Print :CFBundleURLTypes" "/Applications/GitHub Desktop.app/Contents/Info.plist"

This shows all URL schemes the app has registered in its bundle, including x-github-client.

Step 4: Check for stale or conflicting registrations in LaunchServices

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump | grep -i "x-github-client" -B 10

This dumps the LaunchServices database and shows which app is currently bound to the scheme.

The Fix

Option A: Manual fix with PlistBuddy (what I did)

On macOS Tahoe, the LaunchServices secure plist file didn't exist on my system — it only gets created when you've explicitly overridden a default handler. I had to create it from scratch.

First, try re-registering GitHub Desktop with LaunchServices:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -f "/Applications/GitHub Desktop.app"

Then test with open "x-github-client://..." again. If it still opens the wrong app, proceed to manually set the handler:

mkdir -p ~/Library/Preferences/com.apple.LaunchServices
/usr/libexec/PlistBuddy -c "Add :LSHandlers array" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/PlistBuddy -c "Add :LSHandlers:0 dict" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/PlistBuddy -c "Add :LSHandlers:0:LSHandlerURLScheme string x-github-client" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/PlistBuddy -c "Add :LSHandlers:0:LSHandlerRoleAll string com.github.GitHubClient" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/PlistBuddy -c "Add :LSHandlers:0:LSHandlerPreferredVersions dict" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/PlistBuddy -c "Add :LSHandlers:0:LSHandlerPreferredVersions:LSHandlerRoleAll string -" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist

Then restart the LaunchServices daemon:

killall lsd

And test:

open "x-github-client://openRepo/https://github.com/octocat/Hello-World"

GitHub Desktop opened. Problem solved.

Option B: The one-liner (recommended for next time)

After going through all of that, I discovered utiluti — a modern, open-source command-line tool built specifically for managing default app associations on macOS. What took me seven PlistBuddy commands becomes:

brew install scriptingosx/formulae/utiluti
utiluti url set x-github-client com.github.GitHubClient

That's it. You can also inspect the current state:

# See who currently handles the scheme
utiluti url x-github-client --bundle-id

# See all apps registered for it
utiluti url list x-github-client

# Check what schemes GitHub Desktop declares
utiliti app schemes com.github.GitHubClient

Free Tools for Managing URL Scheme Handlers on macOS

Since Apple doesn't provide a UI for this, here are three free tools worth knowing about:

utiluti — Command-line tool, actively maintained, built for modern macOS. Best option for developers comfortable with Terminal. GitHub: github.com/scriptingosx/utiluti Install: brew install scriptingosx/formulae/utiluti

SwiftDefaultApps — A System Settings preference pane with a full GUI. Lets you browse every URL scheme and file type association and change them with a dropdown. Installable via brew install swiftdefaultappsprefpane. Development paused since 2019 but the author has announced plans to resume with updated APIs. GitHub: github.com/Lord-Kamina/SwiftDefaultApps

duti — A lightweight, older command-line tool that still works. Usage: duti -s com.github.GitHubClient x-github-client all Install: brew install duti

Notes for macOS Tahoe (26.x) Users

A couple of things have changed in Tahoe that affect troubleshooting:

The lsregister -kill flag, which was the classic way to nuke and rebuild the LaunchServices database, has been removed in Tahoe. Apple's message: "The -kill option has been removed because it was dangerous and no longer useful." If you need to reset LaunchServices, the current workaround is:

rm -rf ~/Library/Preferences/com.apple.LaunchServices
killall lsd

Be warned: this triggers a wave of permission popups as macOS rebuilds its database from scratch.

The com.apple.launchservices.secure.plist file may not exist at all until you've explicitly set a handler override. Don't be alarmed if it's missing — you can create it with PlistBuddy or just use utiluti which handles everything behind the scenes.

Key Takeaways

macOS has a silent "last app wins" policy for custom URL schemes. Any app can claim any scheme, and the most recently registered one takes over with no notification. The only built-in defaults Apple exposes in System Settings are for web browser and email. For everything else — git clients, Slack, Zoom, Figma, custom deep links — you need third-party tools or command-line knowledge to manage. If you install multiple apps that handle the same URL scheme (GitHub Desktop, SourceTree, Fork, Tower, GitKraken, etc.), expect conflicts. Keep utiluti installed and you'll be able to fix them in seconds.