← Back to PRs

#11455: fix(gateway): default gateway.mode to local when unset

by AnonO6 open 2026-02-07 20:48 View on GitHub →
cli commands stale
#### Summary Fixes #10767 On a clean install (after deleting `~/.openclaw`), the generated `openclaw.json` can end up with `gateway.auth` settings but no `gateway.mode`, causing the gateway to block startup with: `"Gateway start blocked: set gateway.mode=local (current: unset)"`. lobster-biscuit #### Root Cause The gateway config builder functions (`applyNonInteractiveGatewayConfig` and `configureGatewayForOnboarding`) rely on `...nextConfig.gateway` spread to preserve `mode` through multiple object updates (auth, port, bind, tailscale). If `mode` gets lost during any of these spreads (e.g., if the caller's initial config didn't have it), the final config ends up with `gateway.auth` but no `gateway.mode`. #### Fix (three layers) 1. **`src/cli/gateway-cli/run.ts`**: Auto-repair at gateway start — when config exists with gateway settings (auth, port, etc.) but `mode` is missing, default to `"local"` and log a warning. This fixes existing broken configs without requiring manual intervention. 2. **`src/commands/onboard-non-interactive/local/gateway-config.ts`**: Explicitly set `mode: nextConfig.gateway?.mode ?? "local"` in the final gateway object spread instead of relying on preservation through spread. 3. **`src/wizard/onboarding.gateway-config.ts`**: Same defensive explicit set. #### Behavior Changes - Gateway now starts successfully even when `gateway.mode` is missing from config (as long as gateway settings exist). Previously it would error and exit. - Config generation now explicitly preserves `mode` through all spread operations. - No change to the default value — `"local"` is always the intended default for local gateway mode. #### Codebase and GitHub Search - Searched all config-writing paths: `onboarding.ts`, `onboard-non-interactive/local.ts`, `configure.wizard.ts`, `configure.gateway.ts`, `dev.ts` - Verified that all paths intend to set `mode: "local"` but two relied on spread-preservation - Confirmed `configure.gateway.ts` (line 210) and `dev.ts` (line 105) already set `mode` explicitly (not affected) - Confirmed `resolveGatewayPort` pattern exists for port resolution; no equivalent `resolveGatewayMode` existed #### Tests - `pnpm build` ✓ - `pnpm check` ✓ - Added 4 unit tests in `gateway-config.test.ts`: - Preserves existing `mode: "local"` from nextConfig - Defaults `mode` to `"local"` when nextConfig has no mode (the #10767 bug) - Defaults `mode` to `"local"` when `nextConfig.gateway` is undefined - Does not override explicitly set `remote` mode **Sign-Off** - AI-assisted: Yes (Cursor + Claude). All changes reviewed and understood. - Degree of testing: Build + lint + 4 unit tests covering the bug scenario - Models used: Claude claude-4.6-opus - Submitter effort: Root cause investigation across 6+ config-writing paths, defensive multi-layer fix Made with [Cursor](https://cursor.com) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR addresses a startup blocker where `gateway.auth` (or other gateway settings) can be present in `openclaw.json` while `gateway.mode` is missing, causing the gateway CLI to refuse to start. It fixes this in three places: - `src/cli/gateway-cli/run.ts`: runtime “auto-repair” by treating missing `gateway.mode` as `local` when a config exists and `gateway` settings are present. - `src/commands/onboard-non-interactive/local/gateway-config.ts` and `src/wizard/onboarding.gateway-config.ts`: explicitly set `gateway.mode` during config assembly so it can’t be lost across object spreads. - Adds unit tests for `applyNonInteractiveGatewayConfig`. The main concern is that the newly added test file appears to have incorrect relative import paths, which would prevent the test suite from compiling/running. <h3>Confidence Score: 3/5</h3> - Mostly safe, but test compilation may be broken due to incorrect imports. - The functional changes are small and targeted (defaulting `gateway.mode` to `local` when unset), but the added unit test file likely has incorrect relative import paths, which would break CI/test runs until fixed. - src/commands/onboard-non-interactive/local/gateway-config.test.ts <!-- greptile_other_comments_section --> <sub>(5/5) You can turn off certain types of comments like style [here](https://app.greptile.com/review/github)!</sub> <!-- /greptile_comment -->

Most Similar PRs