Homebrew can't uninstall OpenVPN Connect: which path fits?
A failed cask uninstall is one of three faults. Read the cask artifacts, compare versions, then decide between retry, upgrade or zap.
Three different faults wear the same cask error message, and each one has its own recovery path. The vendor uninstaller may be missing from the installed version, a helper may still be running and holding its files, or the package receipt may disagree with what is on disk. The old forum workaround that rescued one of those cases tells you nothing about which one you have. Reading the cask's own record is how you find out.
Three failures that look alike
A missing uninstaller shows up as a path that does not exist when the cask tries to run it. A live helper shows up as a removal that starts and then stalls, or as an application that reappears after you quit it. A stale receipt shows up when the cask's own record and the installer database disagree about whether the product is installed at all.
Keep the first error text before you retry anything. A second attempt overwrites the state that produced the message, and the original line is what a maintainer or vendor needs in order to tell these apart. Copy it somewhere that survives the retry.
If this VPN is carrying the connection you are using to work, arrange another administration path first. Removing the client that provides your access is a decision about the maintenance window, not about Homebrew. That ordering is also what makes a failed uninstall recoverable instead of terminal.
Read what the cask actually installed
Homebrew's own view is the cheapest evidence available, and it does not modify anything:
brew info --cask openvpn-connect
brew list --cask openvpn-connectThe first command prints the cask metadata and the artifacts it manages; the second lists what is recorded as installed. Neither proves that every helper on the machine matches the current recipe, which is exactly why an older installation can fail in a way the current cask source does not describe. Treat the two outputs as a claim to check, not as the final word on what exists.
Compare the recorded version with the application's own version before choosing a path. A mismatch explains a missing uninstaller without any deeper fault, and the answer is an upgrade to the version the cask expects rather than a manual cleanup.
What zap adds, and what it costs
The uninstall stanza of a cask handles the artifacts the recipe declares: quitting the app, unloading launch jobs, removing a login item, forgetting package receipts and deleting the application bundle. That is the normal path, and it is the one that should work.
--zap is a different request. It asks Homebrew to remove user preferences and shared resources as well, and the documentation warns that this can affect other software. In the OpenVPN Connect cask the zap stanza deletes openvpn.keychain-db and clears the user application-support data, which means saved credentials and connection profiles go with it. If the profile came from an organisation, confirm that you can re-enroll before you choose this path.
| Condition | Path that fits | Path to avoid |
|---|---|---|
| Uninstaller path missing after an OS upgrade | Upgrade the cask to the version matching the app | Hand-writing a replacement script |
| Helper still running during removal | Quit the app and its menu agent, then retry | Deleting the bundle while the helper runs |
| Receipt exists but files are gone | Forget the receipt with the cask's own tooling | Recursive deletion of the Caskroom entry |
| You need the machine clean and can re-enroll | Zap, after reading the stanza | Zap on a machine whose profiles you cannot rebuild |
Paths that look decisive and are not
Writing a dummy remove.sh that exits zero is the worst option on the list. It makes the uninstall report success while leaving launch jobs, receipts and application data in place, so the next installation inherits a half-removed product and a record that says otherwise.
Deleting the Caskroom directory or the application bundle by hand produces a similar state from the other direction. Files disappear while the receipt stays. Every later command then has to be reasoned about against a machine that no longer matches its own database.
A repository-wide brew update-reset is a larger intervention than one failed cask justifies. It changes your tap state to fix a problem that was never about tap state, and it can leave you debugging a different Homebrew than the one you started with.
Deciding in order
Work the sequence: read the cask's recorded artifacts, compare versions, quit every running component, retry the ordinary uninstall, and only then consider zap. If the ordinary path still fails, keep the error and take it to the cask maintainers or the vendor with the version numbers attached.
The Cask Cookbook is explicit that package installers need product-specific uninstall techniques and that zap is opt-in and may remove shared resources. That framing is the decision rule: ordinary uninstall first, zap when you accept the credential cost, manual deletion never.