#23285: fix(dashboard): use config.patch for agent edits to prevent agent list truncation
app: web-ui
size: XS
Cluster:
UI Enhancements and Fixes
## Problem
When editing agents via the Control UI dashboard (model, tools, skills, node bindings), the save path used `config.set` which does a full config replacement. If the on-disk config was modified externally between load and save (e.g., another agent added via CLI or another dashboard session), those changes were silently overwritten, causing agents to disappear from the config.
Example: 7 agents → 3 agents after dashboard edit.
This also created orphaned bindings and invalid config keys.
## Root Cause
The dashboard's `saveConfig()` function serializes the entire `configForm` and sends it to `config.set`, which replaces the entire config file. The `configForm` is a snapshot from the last load, so any external changes made after that load are lost.
## Solution
Add `patchAgentsConfig()` that extracts only the `agents` section from the form and sends it via `config.patch`. The `config.patch` endpoint uses `applyMergePatch` with `mergeObjectArraysById: true`, which merges agents by their `id` field. This preserves agents not present in the patch and prevents silent data loss.
## Changes
- **ui/src/ui/controllers/config.ts**: Added `patchAgentsConfig()` function
- **ui/src/ui/app-render.ts**: Wire agents panel and nodes panel saves to use `patchAgentsConfig()` instead of `saveConfig()`
## Affected Save Paths
- Agents panel: model, tools profile, tools overrides, skills (`onConfigSave`)
- Nodes panel: exec node bindings (`onSaveBindings`)
Fixes #23237
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Replaces full config replacement with targeted agent patching to prevent data loss when editing agents via the Control UI dashboard. The fix uses `config.patch` with ID-based merging instead of `config.set`, preserving agents added externally between page load and save.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The fix correctly addresses the root cause by using `config.patch` with ID-based merging instead of full config replacement. The implementation follows existing patterns, has comprehensive test coverage (src/gateway/server.config-patch.e2e.test.ts), and only affects the specific save paths that edit agent configuration.
- No files require special attention
<sub>Last reviewed commit: b5a971b</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#22977: fix(ui): resolve agent names from config in session dropdown
by NikhilGaddam · 2026-02-21
76.6%
#20968: fix(ui): enable save button when editing default agent models
by Gitjay11 · 2026-02-19
75.5%
#17221: fix(agents): prevent agents from using exec for gateway management
by CornBrother0x · 2026-02-15
74.3%
#11854: fix: resolve per-agent tools.exec config in pi-tools
by Yida-Dev · 2026-02-08
73.9%
#17788: fix: correct config path in sessions_spawn error hint (v2)
by Limitless2023 · 2026-02-16
73.8%
#21679: fix: Mission Control dashboard issues for agent status, stale sessi...
by thejawdoc · 2026-02-20
73.5%
#7382: fix: remove config.schema from agent gateway tool
by kakuteki · 2026-02-02
73.2%
#15982: fix: pass agentId to resolveSessionFilePath in reply flow (NX-003)
by automagik-genie · 2026-02-14
72.9%
#10707: fix(ui): prevent agents-main stretching to match sidebar height
by Yida-Dev · 2026-02-06
72.9%
#16362: Update session-pruning.md - updated agents.defaults config std
by elliottb · 2026-02-14
72.0%