#17835: Fix misleading gateway stop hints for standalone listeners
channel: whatsapp-web
cli
size: S
Cluster:
Gateway and macOS Improvements
## Problem
On macOS, users can end up with a standalone `openclaw-gateway` process (not launchd-managed) still listening on the gateway port.
In that state:
- `openclaw gateway stop` / `openclaw gateway start` report `service not loaded`
- `openclaw gateway` lock-error output still suggested `openclaw gateway stop`
- port hints also assumed service-managed stop behavior
That combination sends users into a dead-end.
## Root Cause
Two messaging paths were service-assumptive:
1. GatewayLockError handling in `gateway run`
2. Generic gateway port hints in `infra/ports-format`
Neither checked whether the listener was standalone while service state was `not loaded`.
## What This PR Changes
### 1) Context-aware lock-error guidance
In `src/cli/gateway-cli/run.ts`:
- Added standalone listener detection:
- port is busy
- listener classifies as gateway
- service `isLoaded()` is `false`
- When detected, prints explicit standalone remediation:
- `openclaw gateway --force --port <port>`
- or stop listed PID manually
- Preserves existing service-oriented hints when service is actually loaded.
### 2) Safer generic port hint text
In `src/infra/ports-format.ts`:
- Updated gateway hint to process-oriented guidance instead of always suggesting `openclaw gateway stop`.
### 3) Regression coverage
- `src/cli/gateway-cli.coverage.e2e.test.ts`
- Added scenario for GatewayLockError + service not loaded + gateway listener.
- Asserts standalone guidance is shown and loaded-service wording is not.
- `src/infra/ports.test.ts`
- Added assertion that gateway hints include `--force --port` and no longer require `gateway stop` wording.
## Validation
- `pnpm --dir /Users/connorcallison/code/openclaw exec vitest run --config vitest.unit.config.ts src/infra/ports.test.ts`
- `pnpm --dir /Users/connorcallison/code/openclaw exec vitest run --config vitest.e2e.config.ts src/cli/gateway-cli.coverage.e2e.test.ts`
Both pass.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes misleading error messages when users have standalone `openclaw-gateway` processes (not service-managed) listening on the gateway port on macOS.
**Key changes:**
- Added context-aware lock-error guidance in `src/cli/gateway-cli/run.ts:61-103` that detects standalone gateway listeners and provides appropriate remediation steps
- Updated generic port hint text in `src/infra/ports-format.ts:30` to suggest `--force --port` instead of always suggesting `gateway stop`
- Added comprehensive test coverage for the standalone listener scenario in both e2e and unit tests
The solution correctly distinguishes between service-managed and standalone gateway processes by checking `service.isLoaded()` and only showing standalone guidance when the service is not loaded but a gateway listener is detected on the port.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The implementation is clean, well-tested, and follows existing patterns. The new `maybeExplainStandaloneGatewayProcess` function has proper error handling with try-catch blocks, early returns for edge cases, and defensive checks. Test coverage includes both the new standalone scenario and ensures the existing service-managed scenario still works correctly. The change is localized to error messaging logic and doesn't affect core gateway functionality.
- No files require special attention
<sub>Last reviewed commit: 9861829</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#11147: fix(daemon): stop gateway by port when no daemon service is active
by jasonthewhale · 2026-02-07
79.6%
#9460: fix(gateway): clean up lock file on service stop
by zenchantlive · 2026-02-05
79.3%
#8260: fix(macOS): gateway readiness detection + reversible Configure later
by xksteven · 2026-02-03
79.3%
#11455: fix(gateway): default gateway.mode to local when unset
by AnonO6 · 2026-02-07
77.8%
#21459: fix(gateway): resolve port from profile config, not inherited env
by kkeeling · 2026-02-19
77.8%
#23760: fix(gateway-lock): use port binding as primary liveness signal
by Operative-001 · 2026-02-22
77.8%
#23584: fix(daemon): improve gateway service detection to avoid false posit...
by mohandshamada · 2026-02-22
77.3%
#18236: macOS daemon: bootstrap LaunchAgent on gateway start after stop
by agisilaos · 2026-02-16
77.1%
#22304: Gateway: fix launchd start after stop
by apethree · 2026-02-21
76.8%
#4653: fix(gateway): improve crash resilience for mDNS and network errors
by AyedAlmudarra · 2026-01-30
76.5%