#11208: fix(config): prevent __OPENCLAW_REDACTED__ corruption on config writes
app: macos
stale
Cluster:
Config Redaction Improvements
Fixes a critical bug where Mac app settings could write corrupted config containing `__OPENCLAW_REDACTED__` sentinel values to disk, causing Telegram channels and other services to fail with 404 errors.
## Root Cause
1. **Overly broad redaction pattern**: `SENSITIVE_KEY_PATTERNS` included `/token/i` which matched `maxTokens` (a numeric config field). This caused `maxTokens: 8192` to be redacted as `maxTokens: "__OPENCLAW_REDACTED__"` (number → string type change).
2. **Validation failure → fallback write**: When Mac app sent config via `config.set`, gateway validation rejected the type mismatch. Mac app's fallback path (`ConfigStore.save()`) then wrote the redacted config directly to disk, bypassing `restoreRedactedValues()`.
3. **No guard on direct file writes**: `OpenClawConfigFile.saveDict()` had no protection against writing sentinel values.
## Changes
1. **src/config/redact-snapshot.ts**: Changed pattern to `/(?<!max)token/i` to exclude `maxTokens` while preserving redaction for `botToken`, `accessToken`, `webhookToken`, etc.
2. **apps/macos/Sources/OpenClaw/ConfigStore.swift**: Removed fallback path that wrote directly to disk on `saveToGateway()` failure. Failures now propagate to the caller instead of silently writing corrupted config.
3. **apps/macos/Sources/OpenClaw/OpenClawConfigFile.swift**: Added `containsRedactedSentinel()` guard to reject any config containing `__OPENCLAW_REDACTED__` values before writing to disk.
## Testing
All existing tests pass (959/960; lancedb failure is unrelated). `src/config/redact-snapshot.test.ts` verifies redaction behavior.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes a config-corruption path where redacted `__OPENCLAW_REDACTED__` values could be written to disk from the macOS app. It narrows the sensitive-key redaction regex in `src/config/redact-snapshot.ts`, removes the macOS fallback that wrote configs directly to disk when gateway validation failed (`ConfigStore.save`), and adds a guard in `OpenClawConfigFile.saveDict` to block writes that still contain the sentinel.
Overall this aligns the write path with the intended invariant: sentinel values should never be persisted, and gateway writes should fail rather than silently persisting an invalid/redacted config.
<h3>Confidence Score: 3/5</h3>
- This PR is likely correct, but there are a couple behavior changes that can cause incorrect redaction and silent config-save failures.
- The fix addresses the reported corruption path (remove fallback disk write; block sentinel on disk) and is covered by tests for redaction/restore. Remaining concerns are (1) the new negative-lookbehind regex can under-redact keys beyond just `maxTokens`, and (2) the macOS disk-write guard fails closed but only logs/returns, so callers may silently drop user changes without UI feedback.
- src/config/redact-snapshot.ts; apps/macos/Sources/OpenClaw/OpenClawConfigFile.swift
<!-- greptile_other_comments_section -->
<sub>(4/5) You can add custom instructions or style guidelines for the agent [here](https://app.greptile.com/review/github)!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#21901: fix: guard writeConfigFile against persisting redaction sentinels
by Protocol-zero-0 · 2026-02-20
86.0%
#23654: security(cli): redact sensitive values in config get output
by SleuthCo · 2026-02-22
85.4%
#12792: fix: exclude 'tokens' (plural) fields from config redaction
by jpaine · 2026-02-09
83.5%
#16708: fix(security): OC-17 add token redaction to error formatting, depre...
by aether-ai-agent · 2026-02-15
80.6%
#21124: fix(config): preserve missing keys from original in restoreRedacted...
by Marvae · 2026-02-19
79.8%
#19115: fix(logging): improved redaction for config objects and unquoted keys
by Clawborn · 2026-02-17
78.0%
#19129: fix(config): block destructive config writes instead of only loggin...
by pierreeurope · 2026-02-17
77.8%
#12296: security: persistence-only secret redaction for session transcripts
by akoscz · 2026-02-09
77.5%
#6770: fix(gateway): protect host-local transport fields from config.patch
by ryx2 · 2026-02-02
76.1%
#15050: fix: transcript corruption resilience — strip aborted tool_use bloc...
by yashchitneni · 2026-02-12
75.8%