← Back to PRs

#16301: fix: preserve custom config keys during configure wizard

by superlowburn open 2026-02-14 16:00 View on GitHub →
commands stale size: S
## Summary - Fix `openclaw configure` silently dropping custom config keys not managed by the wizard (e.g. `tools.media.audio`, disabled skills, `gateway.auth.allowTailscale`) - Use `snapshot.resolved` (pre-defaults config) instead of `snapshot.config` (with runtime defaults) as the write base, matching the pattern established by the `config set` fix (#6070) - Add test verifying custom keys survive a wizard run and runtime defaults don't leak ## Root Cause The configure wizard built `nextConfig` from `snapshot.config`, which includes runtime defaults (`agents.defaults.maxConcurrent`, model defaults, etc.). When `writeConfigFile(nextConfig)` was called, the config passed in was bloated with defaults the user never set, while user-specified keys outside the wizard's managed sections were lost. The `config set` command had the same bug (#6070) and was fixed by switching to `snapshot.resolved` — the config after `$include` and `${ENV}` resolution but before runtime defaults are applied. This PR applies the same fix to the configure wizard. ## Changes **`src/commands/configure.wizard.ts`:** - Added `resolvedConfig` derived from `snapshot.resolved` - Changed `nextConfig` base from `{ ...baseConfig }` to `structuredClone(resolvedConfig)` - Changed `promptRemoteGatewayConfig` call to use `resolvedConfig` - `baseConfig` (with defaults) is still used for display values and prompt defaults **`src/commands/configure.wizard.e2e.test.ts`:** - Added test: "preserves custom keys not managed by the wizard" - Updated existing test mocks to include `resolved` field ## Test plan - [x] New test verifies `tools.media.audio`, `skills.entries` (disabled skills), and `gateway.auth.allowTailscale` survive a wizard run - [x] New test verifies runtime defaults (`agents.defaults.maxConcurrent`) do NOT leak into written config - [x] Existing wizard tests pass (3/3) - [x] All config tests pass (386/386) - [x] All command tests pass (52/52) Closes #9632 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Fixes the configure wizard silently dropping custom config keys by switching from `snapshot.config` (includes runtime defaults) to `snapshot.resolved` (pre-defaults config) as the write base. This matches the pattern from PR #6070 which fixed the same issue in `config set`/`unset` commands. The change preserves user-specified keys like `tools.media.audio`, `gateway.auth.allowTailscale`, and disabled skills while preventing runtime defaults from leaking into the written config file. **Key changes:** - Uses `structuredClone(resolvedConfig)` instead of `{ ...baseConfig }` as the base for `nextConfig` - Passes `resolvedConfig` to `promptRemoteGatewayConfig` instead of `baseConfig` - `baseConfig` (with defaults) is still correctly used for display values and prompt defaults - Comprehensive test coverage verifying custom keys survive and runtime defaults don't leak <h3>Confidence Score: 5/5</h3> - Safe to merge with no concerns - The fix directly mirrors the established pattern from PR #6070, uses the correct `snapshot.resolved` field as documented in the type definitions, and includes comprehensive test coverage that validates both preservation of custom keys and prevention of runtime defaults leaking. The changes are minimal, well-commented, and the test explicitly covers the bug scenario. - No files require special attention <sub>Last reviewed commit: d63770e</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs