Skip to content

fix(connector): find cloudflared when launchd's PATH does not have it - #2

Merged
MGrin merged 1 commit into
mainfrom
fix/cloudflared-path-fallback
Aug 15, 2026
Merged

fix(connector): find cloudflared when launchd's PATH does not have it#2
MGrin merged 1 commit into
mainfrom
fix/cloudflared-path-fallback

Conversation

@MGrin

@MGrin MGrin commented Aug 15, 2026

Copy link
Copy Markdown
Owner

After a machine restart the tunnel was dead and could not be brought back: status said not-provisioned, provision printed success and changed nothing, and reload / disable / enable all left the connector in backoff.

Provisioning was never the problem

The persisted state had a valid connector token the whole time. The bb host process had:

PATH=/usr/bin:/bin:/usr/sbin:/sbin

That's launchd's default — and cloudflared lives at /opt/homebrew/bin. So resolveCloudflaredPath returned null, runConnector threw "cloudflared not found on PATH", and the service sat in backoff with no tunnel.

Started from a terminal, bb inherits the user's PATH and it works perfectly. That is exactly why the symptom was "it breaks when I reboot" rather than "it is broken."

A GUI process inherits launchd's environment, not a login shell's, so PATH is not evidence of what is installed on the machine.

The fix

resolveCloudflaredPath now searches the known install prefixes after PATH:

Dir Why
/opt/homebrew/bin Homebrew, Apple silicon
/usr/local/bin Homebrew on Intel, and the official .pkg
/opt/local/bin MacPorts

PATH still wins when it has a hit. The error message now names where it looked, so the next person sees the actual PATH rather than the word "PATH".

Two existing tests asserted behaviour the fallbacks legitimately change — an empty PATH now resolves — so they pass fallbackDirs: [] and keep testing PATH parsing in isolation, rather than being loosened.

Verified live

After reload: cloudflared runs from /opt/homebrew/bin, the service reports running, bb cf-tunnel status reports connected, and 127.0.0.1:20242/ready returns readyConnections: 4.

73 tests pass, 4 new.

🤖 Generated with Claude Code

After a machine restart the tunnel was dead and could not be brought back:
`bb cf-tunnel status` said not-provisioned, `bb cf-tunnel provision` printed
success and changed nothing, and reload/disable/enable all left the connector
in backoff.

Provisioning was never the problem. The persisted state had a valid connector
token the whole time. The bb host process had:

    PATH=/usr/bin:/bin:/usr/sbin:/sbin

which is launchd's default, and cloudflared lives at /opt/homebrew/bin. So
resolveCloudflaredPath returned null, runConnector threw "cloudflared not found
on PATH", and the service sat in backoff with no tunnel. Started from a terminal
bb inherits the user's PATH and it worked perfectly — which is exactly why the
symptom was "it breaks when I reboot" and not "it is broken".

A GUI process inherits launchd's environment, not a login shell's, so PATH is
not evidence of what is installed on the machine. resolveCloudflaredPath now
searches the known install prefixes after PATH: /opt/homebrew/bin (Homebrew on
Apple silicon), /usr/local/bin (Intel Homebrew and the official .pkg) and
/opt/local/bin (MacPorts). PATH still wins when it has a hit.

The error message now names where it looked, so the next person sees the actual
PATH rather than the word "PATH".

Two existing tests asserted behaviour the fallbacks legitimately change — an
empty PATH now resolves — so they pass fallbackDirs: [] and keep testing PATH
parsing in isolation rather than being loosened.

Verified live: after reload, cloudflared runs from /opt/homebrew/bin, the
service reports running, `bb cf-tunnel status` reports connected, and
127.0.0.1:20242/ready returns readyConnections: 4.

73 tests pass, 4 new.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@MGrin
MGrin merged commit 9f0b584 into main Aug 15, 2026
1 check passed
@MGrin
MGrin deleted the fix/cloudflared-path-fallback branch August 15, 2026 07:16
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