#22066: fix(cli): add actionable hints for gateway close errors
gateway
commands
size: S
When users hit gateway connection errors like `pairing required`, `device token mismatch`, or `unauthorized`, the CLI currently shows a raw WebSocket close reason with no guidance on what to do next. This is the #1 source of confusion in issues (#21913, #16305, #21787, #21914).
**Changes:**
- `resolveCloseReasonHint()` in `call.ts` maps common close reasons to specific recovery commands
- `doctor-gateway-health.ts` now distinguishes pairing/token/auth failures instead of lumping them all as "Gateway not running"
**Before:**
```
gateway closed (1008): pairing required
Gateway target: ws://127.0.0.1:18789
Source: local loopback
```
**After:**
```
gateway closed (1008): pairing required
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Hint: Device is not paired with the gateway. Run: openclaw devices approve --latest
```
Doctor also stops saying "Gateway not running" when the gateway IS running but pairing/auth failed.
Tested with `vitest` (6 new tests for hint resolution).
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds actionable hints to gateway connection errors by mapping common close reasons (`pairing required`, `device token mismatch`, `unauthorized`) to specific recovery commands. The `doctor` command now distinguishes between different auth/pairing failures instead of generically reporting "Gateway not running".
**Key changes:**
- New `resolveCloseReasonHint()` function maps close reasons to CLI commands
- Enhanced error formatting in `formatGatewayCloseError()` to append hints
- Updated `doctor-gateway-health.ts` with specific pairing/auth failure messages
- Added 6 test cases for hint resolution
**Issue found:**
- The scope-upgrade hint logic on call.ts:312-314 is unreachable - the gateway always sends `"pairing required"` for scope upgrades, never `"scope-upgrade"`. The test on line 17-20 of call.close-hints.test.ts validates functionality that won't execute in practice.
<h3>Confidence Score: 3/5</h3>
- Safe to merge with one logical error in unreachable code
- The PR successfully implements helpful user-facing error hints and has good test coverage. However, there's a logical error where the scope-upgrade condition will never match actual gateway behavior (the gateway sends "pairing required" not "scope-upgrade" for scope upgrades). This doesn't break functionality since the fallback "pairing required" handler works correctly, but it means the scope-specific hint and its test are unreachable. The implementation is otherwise sound and well-tested.
- src/gateway/call.ts needs the scope-upgrade logic fixed (lines 312-314)
<sub>Last reviewed commit: 51e9d74</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22262: fix(gateway): add pairing-repair command hint on 1008 connect failures
by karimnaguib · 2026-02-20
84.6%
#21148: fix(gateway): add request-aware pairing recovery hints and docs
by cluster2600 · 2026-02-19
83.7%
#22712: fix(gateway): auto-approve all device pairing for localhost connect...
by NewdlDewdl · 2026-02-21
77.5%
#21651: fix(gateway): token fallback + operator.admin scope superset in pai...
by lan17 · 2026-02-20
77.5%
#19088: fix(gateway): allow startup with unset mode and fix pairing for local…
by mdanassaif · 2026-02-17
77.5%
#17425: fix(gateway): auto-approve scope/role upgrades for already-paired d...
by sauerdaniel · 2026-02-15
77.3%
#22280: fix(gateway): silently auto-approve local paired-device scope upgrades
by abhishekp76 · 2026-02-21
76.6%
#22327: fix(doctor): use gateway health status for memory search key check
by therk · 2026-02-21
76.3%
#21622: fix(gateway): include read/write in CLI default operator scopes
by zerone0x · 2026-02-20
76.1%
#16310: fix(ws-connection): skip device pairing when client authenticates w...
by nawinsharma · 2026-02-14
76.1%