Bug type
Regression (worked before, now fails)
Summary
I tracked a cluster of iOS gateway onboarding failures to four related issues.
Steps to reproduce
- Manual LAN connect to
ws://192.168.x.x:18789 or ws://openclaw.local:18789 hangs/fails before auth.
- The iOS app discovers the gateway and HTTP works, but WebSocket onboarding via setup code hangs.
- Manually entering the shared gateway auth token works immediately.
Expected behavior
Connects properly
Actual behavior
iOS was silently rewriting local-network ws:// inputs to wss://
apps/ios/Sources/Gateway/GatewayConnectionController.swift:164
apps/ios/Sources/Gateway/GatewayConnectionController.swift:711
- The manual path treated any non-loopback host as TLS-required.
- That means valid LAN hosts like
192.168.x.x, .local, Tailscale addresses, and .ts.net were being upgraded to wss:// before auth, which breaks plain-LAN gateways.
- Local fix: allow plaintext for local-network hosts and log TLS overrides / trust-probe failures.
- Bootstrap setup keys are single-use, but iOS opens two sockets in parallel
apps/ios/Sources/Model/NodeAppModel.swift:1713
apps/ios/Sources/Model/NodeAppModel.swift:1722
src/infra/device-bootstrap.ts:110
src/gateway/server/ws-connection/message-handler.ts:766
- iOS starts both
operator and node sessions with the same bootstrap token.
- The bootstrap token is consumed on first successful verification.
- One socket can hit
PAIRING_REQUIRED, while the other immediately gets AUTH_BOOTSTRAP_TOKEN_INVALID.
- Result: setup-code onboarding stalls.
- The QR/setup-code generator was forcing the broken bootstrap path
src/pairing/setup-code.ts:15
src/pairing/setup-code.ts:376
- The generator emitted only
{ url, bootstrapToken }, even though the iOS parser already supports token and password.
- That means QR onboarding could not use the same shared gateway credential that already works when entered manually.
- Local fix: emit the resolved shared
token or password in the setup payload instead of bootstrap-only auth.
- Mixed auth preferred bootstrap over password
apps/shared/OpenClawKit/Sources/OpenClawKit/GatewayChannel.swift:516
src/gateway/client.ts:518
- If both
bootstrapToken and password were present, the client still chose bootstrap auth first.
- That makes mixed payloads and stale stored bootstrap state behave incorrectly.
- Local fix: suppress bootstrap auth whenever an explicit password is present.
Why I think this is the right fix
- Manual shared-token auth succeeds against the same gateway.
- Raw HTTP and WebSocket reachability were both healthy.
- The failing path was specifically setup-code/bootstrap onboarding.
Suggested maintainer actions
- Keep the iOS LAN
ws:// fix.
- Stop generating bootstrap-only setup codes when shared gateway auth is available.
- Keep password-over-bootstrap precedence in both Swift and TypeScript clients.
- Longer-term: revisit whether single-use bootstrap tokens are compatible with the current multi-socket onboarding flow at all.
Validated locally with
- targeted TypeScript tests for setup-code generation and gateway auth selection
- Swift
GatewayChannelConnectTests
- successful iOS app build and device install
OpenClaw version
2026.3.13
Operating system
Macos 12
Install method
No response
Model
OpenAI 5.4
Provider / routing chain
openclaw LAN
Config file / key location
No response
Additional provider/model setup details
No response
Logs, screenshots, and evidence
Impact and severity
No response
Additional information
No response
Bug type
Regression (worked before, now fails)
Summary
I tracked a cluster of iOS gateway onboarding failures to four related issues.
Steps to reproduce
ws://192.168.x.x:18789orws://openclaw.local:18789hangs/fails before auth.Expected behavior
Connects properly
Actual behavior
iOS was silently rewriting local-network
ws://inputs towss://apps/ios/Sources/Gateway/GatewayConnectionController.swift:164apps/ios/Sources/Gateway/GatewayConnectionController.swift:711192.168.x.x,.local, Tailscale addresses, and.ts.netwere being upgraded towss://before auth, which breaks plain-LAN gateways.apps/ios/Sources/Model/NodeAppModel.swift:1713apps/ios/Sources/Model/NodeAppModel.swift:1722src/infra/device-bootstrap.ts:110src/gateway/server/ws-connection/message-handler.ts:766operatorandnodesessions with the same bootstrap token.PAIRING_REQUIRED, while the other immediately getsAUTH_BOOTSTRAP_TOKEN_INVALID.src/pairing/setup-code.ts:15src/pairing/setup-code.ts:376{ url, bootstrapToken }, even though the iOS parser already supportstokenandpassword.tokenorpasswordin the setup payload instead of bootstrap-only auth.apps/shared/OpenClawKit/Sources/OpenClawKit/GatewayChannel.swift:516src/gateway/client.ts:518bootstrapTokenandpasswordwere present, the client still chose bootstrap auth first.Why I think this is the right fix
Suggested maintainer actions
ws://fix.Validated locally with
GatewayChannelConnectTestsOpenClaw version
2026.3.13
Operating system
Macos 12
Install method
No response
Model
OpenAI 5.4
Provider / routing chain
openclaw LAN
Config file / key location
No response
Additional provider/model setup details
No response
Logs, screenshots, and evidence
Impact and severity
No response
Additional information
No response