#19429: Fix/custom bind host validation
gateway
size: S
Cluster:
Config Fixes and Features
Fixes a config validation mismatch that breaks `configure` when selecting a custom Gateway bind IP.
## Problem
When running `openclaw configure` and choosing Gateway bind mode `custom`, the wizard writes:
- `gateway.bind = "custom"`
- `gateway.customBindHost = "<ip>"`
Config validation then fails with:
`Config validation failed: gateway: Unrecognized key: "customBindHost"`
## Root cause
`GatewayConfig` types and runtime code already support `gateway.customBindHost`, but `OpenClawSchema.gateway` in `src/config/zod-schema.ts` did not include this key.
## Fix
- Added `gateway.customBindHost` as an optional string in `src/config/zod-schema.ts`.
- Added regression coverage in `src/config/config.schema-regressions.test.ts` to validate:
- `{ gateway: { bind: "custom", customBindHost: "172.18.0.4" } }`
## Result
`configure` no longer fails after selecting a custom gateway IP, and schema/type/runtime behavior is now aligned.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a config validation mismatch introduced by the `.strict()` Zod schema on the `gateway` object: `customBindHost` was already part of the `GatewayConfig` TypeScript type and used throughout the runtime, but was absent from `OpenClawSchema.gateway` in `zod-schema.ts`, causing `openclaw configure` to fail after selecting a custom bind IP.
Key changes:
- **`src/config/zod-schema.ts`**: Adds the missing `customBindHost: z.string().optional()` field to the gateway Zod schema — the core fix.
- **`src/gateway/call.ts`**: Adds client-side URL resolution for `bind: "custom"`, using `node:net`'s `isIPv4` to validate the host before constructing the WebSocket URL, with a silent fallback to loopback on invalid input.
- **`src/config/config.schema-regressions.test.ts`**: Adds a regression test to prevent the schema omission from recurring.
- **`src/gateway/call.ts` tests**: Adds coverage for the new custom-bind URL resolution path.
The fix is minimal, well-targeted, and aligns schema, type, and runtime behavior. The `call.ts` changes add functionality (client-side custom bind host resolution for RPC calls) that was previously broken alongside the schema fix.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge — it is a targeted schema alignment fix with no behavioral regressions.
- The change is minimal and fixes a clear, documented omission. The `GatewayConfig` type, runtime code, configure wizard, and all downstream consumers already expected `customBindHost` to exist; the schema was simply missing the field. The added `call.ts` logic correctly validates IPv4 input and falls back gracefully. Tests are appropriate and focused. No security implications, no breaking changes.
- No files require special attention.
<sub>Last reviewed commit: f972c02</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
#12499: fix(config): add missing customBindHost to gateway Zod schema
by sfo2001 · 2026-02-09
90.6%
#19437: Gateway: respect custom bind host for local health/RPC target resol...
by frudas24 · 2026-02-17
84.7%
#23688: fix(gateway): accept raw IP addresses in gateway.bind for backward ...
by arosstale · 2026-02-22
81.2%
#21741: fix(gateway): allow plaintext ws:// for Docker/private network addr...
by Joe3112 · 2026-02-20
77.5%
#14564: fix(gateway): crashes on startup when tailscale meets non-loopback ...
by yinghaosang · 2026-02-12
77.0%
#19020: bugfix(gateway): Handle invalid model provider API config gracefully\…
by funkyjonx · 2026-02-17
76.8%
#11455: fix(gateway): default gateway.mode to local when unset
by AnonO6 · 2026-02-07
76.7%
#10807: fix(config): coerce numeric meta.lastTouchedAt to ISO string
by mcaxtr · 2026-02-07
76.6%
#22056: fix(gateway): use loopback for self-connections regardless of bind ...
by usedhonda · 2026-02-20
76.6%
#14179: fix(config): resolve $include directives before validation in setup...
by ken2190 · 2026-02-11
75.7%