#5823: fix(config): exit cleanly on invalid config instead of high CPU loop
Cluster:
Gateway Error Handling Improvements
## Summary
Fixes #5789 - When `agents.defaults.model` has invalid schema, gateway now exits cleanly instead of returning empty config `{}` which causes 100%+ CPU.
## Changes
### `src/config/io.ts`
- Added `shouldExitOnInvalidConfig()` helper that checks `OPENCLAW_EXIT_ON_INVALID_CONFIG` env var
- Default: **true** for gateway mode (detected via `process.title === 'openclaw'` or `OPENCLAW_GATEWAY_MODE=1`)
- Default: **false** for CLI tools (one-shot commands)
- Added `formatConfigErrorHelp()` to provide helpful hints for common schema mistakes
- Modified `INVALID_CONFIG` catch block to call `process.exit(1)` with helpful error message when exit is enabled
### `src/config/config.invalid-exit.test.ts` (new)
- 6 tests covering:
- Exit with code 1 when `OPENCLAW_EXIT_ON_INVALID_CONFIG=1`
- Returns empty config when `OPENCLAW_EXIT_ON_INVALID_CONFIG=0`
- Exits by default when `process.title === 'openclaw'` (gateway mode)
- Exits when `OPENCLAW_GATEWAY_MODE=1`
- Includes helpful error messages for common mistakes
- Hot-reload path logs warning but doesn't exit (keeps old config)
## Backwards Compatibility
The fix is fully backwards compatible:
- **Gateway startup** with invalid config → `exit(1)` with helpful message
- **Gateway hot-reload** with invalid config → log warning, keep old config (no exit)
- **CLI tools** → return empty config (existing behavior, unless env var set)
## Environment Variables
| Variable | Effect |
|----------|--------|
| `OPENCLAW_EXIT_ON_INVALID_CONFIG=1` | Force exit on invalid config |
| `OPENCLAW_EXIT_ON_INVALID_CONFIG=0` | Disable exit, return empty config |
| `OPENCLAW_GATEWAY_MODE=1` | Alternative way to enable gateway behavior |
## Testing
- ✅ TypeScript compiles (`npx tsc --noEmit`)
- ✅ Lint passes (`oxlint`)
- ✅ New tests pass (6/6)
- ✅ Existing `io.compat.test.ts` tests pass (3/3)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR changes config loading so that when schema validation fails (`code === "INVALID_CONFIG"`), gateway-mode processes can exit with a clear error instead of returning `{}` (which previously could trigger a tight high-CPU loop). It adds helpers to decide when to exit based on env/process mode and to append “common mistake” hints, plus a new vitest file covering exit vs fallback behavior and hot-reload snapshot behavior.
Overall the change fits into the existing `createConfigIO().loadConfig()` error-handling path and keeps `readConfigFileSnapshot()` as the non-exiting hot-reload-friendly path.
<h3>Confidence Score: 4/5</h3>
- This PR is reasonably safe to merge and improves failure behavior for invalid configs.
- Changes are localized to config IO error handling with targeted tests, and the new behavior is gated to gateway mode by default or explicit env vars. Main residual concern is control-flow ambiguity around `process.exit(1)` (especially under test/mocked exit), which is easy to address.
- src/config/io.ts (invalid-config exit control flow)
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#10034: Don't crash gateway on transient unhandled fetch failures
by gigq · 2026-02-06
81.8%
#11455: fix(gateway): default gateway.mode to local when unset
by AnonO6 · 2026-02-07
81.6%
#13408: fix(gateway): skip SIGUSR1 restart in config.patch for noop reload ...
by rwmjhb · 2026-02-10
80.9%
#13960: fix(ui): preserve structured config validation error details
by constansino · 2026-02-11
80.7%
#15306: fix: explicit exit after onboarding command completes
by jeroenbaas · 2026-02-13
80.4%
#21994: Config: load valid backup when primary config is invalid
by islavutin · 2026-02-20
79.4%
#3396: Config: gateway.unhandledRejections (warn|exit)
by diegoaledesma · 2026-01-28
79.1%
#8713: feat: gateway memory monitor, install linger, docs and failover
by quratus · 2026-02-04
79.0%
#22720: fix: notify sessions on invalid config during hot-reload
by jayleekr · 2026-02-21
79.0%
#7382: fix: remove config.schema from agent gateway tool
by kakuteki · 2026-02-02
79.0%