Bug: Production pairing broken — POST /api/pairing/mobile returns Route not found
Summary
termly start on production (wss://api.termly.dev / https://api.termly.dev) successfully registers the pairing code via POST /api/pairing and shows QR/code. Scanning immediately on the mobile app fails 100% — the app shows “pair code expired” after ~1s, but the real error is hidden in mobile logs as Route not found.
Mobile logs (ArkWeb, repeated across 6 attempts, 16:54–17:18, all within 5-min TTL)
16:57:12.271 INFO [PAIR] Starting pairing: code=A3CGZZ, server=wss://api.termly.dev
16:57:12.271 INFO [CRYPTO] Generating DH keypair (DH_modp2048)...
16:57:12.286 INFO [PAIR] Calling REST /api/pairing/mobile...
16:57:13.337 ERROR [PAIR] Pairing failed: Pairing failed: Route not found
16:57:13.338 WARN [PAIR] QR pairing failed: Pairing failed: Route not found
# same for codes 90HFBK, KICCX7, MAXXC7 — both QR scan and re-scan paths
CLI repro (production, bypassing mobile)
termly --version # 1.9.5 (latest, verified via npm view @termly-dev/cli)
termly status # OpenCode 1.18.21 detected, Production env
# CLI register endpoint — exists:
curl -X POST https://api.termly.dev/api/pairing \
-H "Content-Type: application/json" -d '{"code":"TEST12","publicKey":"x","projectName":"p","workingDir":"/tmp","computerName":"c","aiTool":"opencode","aiToolVersion":"1.0"}'
# → {"error":"Validation failed", ...} (route hit, validation runs)
# Mobile claim endpoint — missing:
curl -X POST https://api.termly.dev/api/pairing/mobile \
-H "Content-Type: application/json" -d '{"code":"TEST12","publicKey":"x"}'
# → {"error":"Route not found"}
# Same with X-API-Type: cli, with/without proxy (http://localhost:7897), direct — all 404
# Probing alternatives also 404: /api/pairing/claim, /api/pairings/mobile, /api/mobile/pairing, /api/v1/pairing/mobile
Alternate probe:
for p in /api/pairing/claim /api/pairings/mobile /api/mobile/pairing /api/v1/pairing/mobile; do
curl -s -X POST https://api.termly.dev$p -d '{}' | head
done
# all {"error":"Route not found"}
dev-api.termly.dev also returns empty/404 for the same path.
Impact
All mobile pairing on Production is blocked. QR codes are generated and WS Connected to server succeeds (~/.termly/logs/cli.log shows Connected to server), but the mobile claim never lands, so the code just expires and the CLI eventually hits pairing_expired on WS close. The user-facing “code expired” message is misleading — the actual failure is immediate Route not found (~600ms after Calling REST /api/pairing/mobile).
Environment
- CLI:
@termly-dev/cli@1.9.5 (npm latest), termly --version + termly tools detect → OpenCode 1.18.21, Claude Code 2.1.239 also installed
- Server: Production
wss://api.termly.dev / https://api.termly.dev (clock NTP-synced, proxy http://localhost:7897, NO_PROXY=localhost,127.0.0.1, both proxied and direct curl 404)
- Mobile: ArkWeb engine, system time auto-sync, same Production env in QR (
server=wss://api.termly.dev); re-tried with multiple fresh codes (A3CGZZ, 90HFBK, KICCX7, MAXXC7) within seconds of generation.
Expected
POST /api/pairing/mobile should accept the mobile DH pubkey + code and return pairing success, triggering pairing_complete over WS to the CLI (as displayPairingUI / registerPairingCode flow intends). Server should either restore the route or document the correct mobile endpoint if renamed.
Please check
Deployment parity — it looks like POST /api/pairing was deployed but POST /api/pairing/mobile was not / was renamed without a mobile-app release to match. Related to #45 (“Can’t sign in on mobile app after session expired”) but distinct root cause (404 vs expiry handling).
Bug: Production pairing broken —
POST /api/pairing/mobilereturnsRoute not foundSummary
termly starton production (wss://api.termly.dev/https://api.termly.dev) successfully registers the pairing code viaPOST /api/pairingand shows QR/code. Scanning immediately on the mobile app fails 100% — the app shows “pair code expired” after ~1s, but the real error is hidden in mobile logs asRoute not found.Mobile logs (ArkWeb, repeated across 6 attempts, 16:54–17:18, all within 5-min TTL)
CLI repro (production, bypassing mobile)
Alternate probe:
dev-api.termly.devalso returns empty/404 for the same path.Impact
All mobile pairing on Production is blocked. QR codes are generated and WS
Connected to serversucceeds (~/.termly/logs/cli.logshowsConnected to server), but the mobile claim never lands, so the code just expires and the CLI eventually hitspairing_expiredon WS close. The user-facing “code expired” message is misleading — the actual failure is immediateRoute not found(~600ms afterCalling REST /api/pairing/mobile).Environment
@termly-dev/cli@1.9.5(npm latest),termly --version+termly tools detect→ OpenCode 1.18.21, Claude Code 2.1.239 also installedwss://api.termly.dev/https://api.termly.dev(clock NTP-synced, proxyhttp://localhost:7897,NO_PROXY=localhost,127.0.0.1, both proxied and direct curl 404)server=wss://api.termly.dev); re-tried with multiple fresh codes (A3CGZZ, 90HFBK, KICCX7, MAXXC7) within seconds of generation.Expected
POST /api/pairing/mobileshould accept the mobile DH pubkey + code and return pairing success, triggeringpairing_completeover WS to the CLI (asdisplayPairingUI/registerPairingCodeflow intends). Server should either restore the route or document the correct mobile endpoint if renamed.Please check
Deployment parity — it looks like
POST /api/pairingwas deployed butPOST /api/pairing/mobilewas not / was renamed without a mobile-app release to match. Related to #45 (“Can’t sign in on mobile app after session expired”) but distinct root cause (404 vs expiry handling).