← Back to PRs

#19129: fix(config): block destructive config writes instead of only logging them (#19065)

by pierreeurope open 2026-02-17 12:11 View on GitHub →
size: S
## Problem Fixes #19065 The gateway's config write audit correctly detected destructive writes (>50% size drop, `gateway.mode` removed), but only logged them as warnings and allowed the write through. This has caused production outages when a truncated or corrupted config was silently persisted. ## Solution After computing suspicious reasons, filter to the hard-blocking ones (`size-drop:*` and `gateway-mode-removed`). If any are present: 1. **Block the write** — the original `openclaw.json` is left untouched 2. **Save rejected payload** to `openclaw.json.rejected` for debugging 3. **Log a clear error** message identifying the reason(s) 4. **Append a `rejected` audit record** to `config-audit.jsonl` for forensics 5. **Throw** so the caller is informed The informational `missing-meta-before-write` reason is intentionally excluded from the blocking set — it is diagnostic, not destructive, and fires on all pre-meta configs. ## Changes - `src/config/io.ts`: Add `"rejected"` to `ConfigWriteAuditResult`; add blocking guard after suspicious-reason computation - `src/config/io.write-config.test.ts`: Two new test cases — size-drop block and gateway-mode-removed block ## Testing All 363 unit tests in `src/config/` pass: ``` Test Files 47 passed (47) Tests 363 passed (363) ``` New tests cover: - Write blocked + original file untouched + `.rejected` file created + error logged (size-drop) - Write blocked + original file untouched + audit record has `result: "rejected"` (gateway-mode-removed) <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR upgrades the config write audit system from warning-only to hard-blocking for destructive writes. Previously, the system detected dangerous config writes (>50% size drops and `gateway.mode` removal) but only logged warnings, leading to production outages when corrupted configs were persisted. Now, when blocking reasons are detected, the write is rejected, the original file remains untouched, and the rejected payload is saved to `.rejected` for debugging with a full audit trail. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with no identified issues - The implementation is well-designed with proper error handling, the blocking logic is conservative and only targets truly destructive scenarios, comprehensive test coverage validates all the blocking behaviors, and the change transforms a critical production issue into a preventive safeguard - No files require special attention <sub>Last reviewed commit: be4f245</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs