openclaw - 💡(How to fix) Fix Dashboard/macOS app config writes can strip meta/gateway.mode, triggering auto-restore churn [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74890Fetched 2026-05-01 05:40:16
View on GitHub
Comments
1
Participants
2
Timeline
1
Reactions
2
Author
Timeline (top)
commented ×1

On macOS/OpenClaw 2026.4.27, the Control UI / macOS app config writer can write ~/.openclaw/openclaw.json without the required config envelope fields (meta and/or gateway.mode). The gateway detects this as a critical clobber and restores from openclaw.json.last-good, but this can create a repeated restore/churn window and leave the gateway degraded or timing out.

This appears distinct from the existing concurrent-write invalid JSON race in #70643: in this case the written JSON can be syntactically valid, but semantically stripped of required envelope fields. It is also related to the closed recovery issue #70336 only in that recovery now works; the writer is still producing bad snapshots.

Error Message

[channels] failed to load bundled channel qqbot: ENOENT: no such file or directory, open '<home>/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-.../dist/credential-planner-Cm-IPlWf.js' [openclaw] Failed to start CLI: Error: gateway timeout after 10000ms Gateway target: ws://127.0.0.1:18789 Source: local loopback Bind: loopback

Root Cause

On macOS/OpenClaw 2026.4.27, the Control UI / macOS app config writer can write ~/.openclaw/openclaw.json without the required config envelope fields (meta and/or gateway.mode). The gateway detects this as a critical clobber and restores from openclaw.json.last-good, but this can create a repeated restore/churn window and leave the gateway degraded or timing out.

This appears distinct from the existing concurrent-write invalid JSON race in #70643: in this case the written JSON can be syntactically valid, but semantically stripped of required envelope fields. It is also related to the closed recovery issue #70336 only in that recovery now works; the writer is still producing bad snapshots.

Code Example

{
  "source": "macos-openclaw-config-file",
  "event": "config.write",
  "argv": ["/Applications/OpenClaw.app/Contents/MacOS/OpenClaw"],
  "hasMetaBefore": true,
  "hasMetaAfter": true,
  "gatewayModeBefore": "local",
  "gatewayModeAfter": null,
  "suspicious": ["gateway-mode-removed"]
}

---

{
  "event": "config.observe",
  "valid": true,
  "hasMeta": true,
  "gatewayMode": null,
  "suspicious": ["gateway-mode-missing-vs-last-good"],
  "lastKnownGoodGatewayMode": "local"
}

---

{
  "source": "macos-openclaw-config-file",
  "event": "config.write",
  "gatewayModeBefore": null,
  "gatewayModeAfter": "remote",
  "suspicious": []
}

---

{
  "source": "macos-openclaw-config-file",
  "event": "config.write",
  "gatewayModeBefore": "remote",
  "gatewayModeAfter": "local",
  "suspicious": []
}

---

{
  "source": "config-io",
  "event": "config.observe",
  "valid": false,
  "hasMeta": false,
  "gatewayMode": null,
  "suspicious": [
    "missing-meta-vs-last-good",
    "gateway-mode-missing-vs-last-good"
  ],
  "lastKnownGoodGatewayMode": "local",
  "restoredFromBackup": false
}

---

{
  "source": "config-io",
  "event": "config.observe",
  "valid": false,
  "hasMeta": false,
  "gatewayMode": null,
  "suspicious": ["reload-invalid-config"],
  "restoredFromBackup": true,
  "restoredBackupPath": "<home>/.openclaw/openclaw.json.last-good"
}

---

[channels] failed to load bundled channel qqbot: ENOENT: no such file or directory, open '<home>/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-.../dist/credential-planner-Cm-IPlWf.js'
[openclaw] Failed to start CLI: Error: gateway timeout after 10000ms
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Bind: loopback

---

Gateway reachable 134-265ms
openclaw health --json: ok=true, durationMs≈246, plugins.errors=[]
RAW_BUFFERClick to expand / collapse

Summary

On macOS/OpenClaw 2026.4.27, the Control UI / macOS app config writer can write ~/.openclaw/openclaw.json without the required config envelope fields (meta and/or gateway.mode). The gateway detects this as a critical clobber and restores from openclaw.json.last-good, but this can create a repeated restore/churn window and leave the gateway degraded or timing out.

This appears distinct from the existing concurrent-write invalid JSON race in #70643: in this case the written JSON can be syntactically valid, but semantically stripped of required envelope fields. It is also related to the closed recovery issue #70336 only in that recovery now works; the writer is still producing bad snapshots.

Environment

  • OpenClaw: 2026.4.27
  • Install: pnpm/global package path under macOS user Library
  • OS: macOS 26.5 arm64
  • Node: v25.9.0
  • Gateway: LaunchAgent, local loopback, gateway.mode: local, gateway.bind: loopback
  • Tailscale exposure: serve mode configured
  • Active plugins observed after restart: acpx, bonjour, browser, device-pair, llm-task, memory-core, memory-wiki, phone-control, talk-voice, telegram

Private paths, tokens, hostnames, and user/session content are intentionally omitted or redacted.

Observed symptoms

A user saw a cluster of problems after update / config churn:

  • CLI health/status timeouts against ws://127.0.0.1:18789
  • Gateway process high CPU / event-loop delay warnings
  • Plugin runtime errors around bundled channels/internal imports (telegram, qqbot)
  • Runtime-deps mirror regeneration wiping manual fixes
  • Active-memory runs wired to a slow/reasoning model with a 15s budget, causing repeated timeout behavior
  • Dashboard/Control UI writes config without required meta / gateway.mode, triggering auto-restore loop

After disabling noisy plugins and restarting the gateway, openclaw status --deep and openclaw health --json recovered, but the config-audit log showed the config clobber/restore behavior clearly.

Evidence: config writer stripped gateway.mode

From config-audit.jsonl, the macOS app wrote a config where gateway.mode was removed even though meta was still present:

{
  "source": "macos-openclaw-config-file",
  "event": "config.write",
  "argv": ["/Applications/OpenClaw.app/Contents/MacOS/OpenClaw"],
  "hasMetaBefore": true,
  "hasMetaAfter": true,
  "gatewayModeBefore": "local",
  "gatewayModeAfter": null,
  "suspicious": ["gateway-mode-removed"]
}

Immediately afterward the gateway/config observer flagged the live config as suspicious compared with last-known-good:

{
  "event": "config.observe",
  "valid": true,
  "hasMeta": true,
  "gatewayMode": null,
  "suspicious": ["gateway-mode-missing-vs-last-good"],
  "lastKnownGoodGatewayMode": "local"
}

The app then wrote a new config changing gateway.mode from null to remote, then shortly after back to local:

{
  "source": "macos-openclaw-config-file",
  "event": "config.write",
  "gatewayModeBefore": null,
  "gatewayModeAfter": "remote",
  "suspicious": []
}
{
  "source": "macos-openclaw-config-file",
  "event": "config.write",
  "gatewayModeBefore": "remote",
  "gatewayModeAfter": "local",
  "suspicious": []
}

Evidence: later writer removed both meta and gateway.mode

A later gateway read saw a syntactically invalid/semantically clobbered config with both required fields missing and restored from last-good:

{
  "source": "config-io",
  "event": "config.observe",
  "valid": false,
  "hasMeta": false,
  "gatewayMode": null,
  "suspicious": [
    "missing-meta-vs-last-good",
    "gateway-mode-missing-vs-last-good"
  ],
  "lastKnownGoodGatewayMode": "local",
  "restoredFromBackup": false
}

Then on the next observe:

{
  "source": "config-io",
  "event": "config.observe",
  "valid": false,
  "hasMeta": false,
  "gatewayMode": null,
  "suspicious": ["reload-invalid-config"],
  "restoredFromBackup": true,
  "restoredBackupPath": "<home>/.openclaw/openclaw.json.last-good"
}

Evidence: runtime impact around the same incident

Before restart:

[channels] failed to load bundled channel qqbot: ENOENT: no such file or directory, open '<home>/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-.../dist/credential-planner-Cm-IPlWf.js'
[openclaw] Failed to start CLI: Error: gateway timeout after 10000ms
Gateway target: ws://127.0.0.1:18789
Source: local loopback
Bind: loopback

Gateway process was observed around one busy core before restart. After restart:

Gateway reachable 134-265ms
openclaw health --json: ok=true, durationMs≈246, plugins.errors=[]

But logs still showed an event-loop delay warning shortly after recovery.

Expected behavior

  • Dashboard/Control UI/macOS app config writes should preserve mandatory root envelope fields such as meta and gateway.mode unless intentionally changing them through a validated full-config migration.
  • Config writes should be schema-validated before replacing the live config.
  • A UI writer should not temporarily write a partial config shape that the gateway then treats as a clobber.
  • Auto-restore should remain a last-resort safety net, not part of normal UI config update flow.

Actual behavior

  • The macOS app/config UI writer produced snapshots with gateway.mode removed, and later a snapshot with both meta and gateway.mode missing.
  • The gateway detected and restored the bad config, but the system entered a degraded/churny state with CLI timeouts and high CPU until restart.

Related issues

  • #70643 — concurrent writes can produce invalid concatenated JSON. Related locking/atomicity area, but this report is about valid/partial snapshots missing required fields.
  • #70336 — recovery for critical config clobbers. Recovery appears to work now, but this report is about preventing the clobber.
  • #72338 — gateway CPU spin/status timeout symptoms.
  • #74777 / #72992 — plugin-runtime-deps retention/mirror failures, which may be part of the same degraded startup/runtime cluster.
  • #66804 / #73306 / #73801 — active-memory 15s timeout/model-selection symptoms.

Suggested fix

  1. Audit all Control UI / macOS app config write paths for partial root writes.
  2. Route them through the same atomic, locked read/merge/validate/write path as CLI config mutations.
  3. Add regression tests where UI/dashboard changes preserve meta, gateway.mode, auth, reload, and other root gateway fields.
  4. Treat writes that remove mandatory envelope fields as rejected before rename, not as recoverable live clobbers.
  5. Consider adding a clearer diagnostic that names the writer/source and path when gateway-mode-removed or missing-meta-vs-last-good is observed.

extent analysis

TL;DR

The Control UI/macOS app config writer should be modified to preserve mandatory root envelope fields such as meta and gateway.mode during config writes.

Guidance

  • Review the config write paths in the Control UI/macOS app to ensure they handle partial root writes correctly.
  • Implement atomic, locked read/merge/validate/write operations for config mutations to prevent data corruption.
  • Add regression tests to verify that UI/dashboard changes preserve required root gateway fields.
  • Update the gateway to reject config writes that remove mandatory envelope fields instead of treating them as recoverable clobbers.
  • Consider adding diagnostic messages to identify the writer/source and path when mandatory fields are missing.

Example

No code snippet is provided as the issue description does not include specific code that needs to be modified. However, the suggested fix implies that the config write function should be updated to include validation and error handling for mandatory fields.

Notes

The provided issue description suggests that the problem is related to the Control UI/macOS app config writer, but the exact cause and solution may require further investigation and testing.

Recommendation

Apply the suggested fix by modifying the Control UI/macOS app config writer to preserve mandatory root envelope fields and implement atomic, locked config mutations. This should prevent the gateway from entering a degraded state due to partial config writes.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

  • Dashboard/Control UI/macOS app config writes should preserve mandatory root envelope fields such as meta and gateway.mode unless intentionally changing them through a validated full-config migration.
  • Config writes should be schema-validated before replacing the live config.
  • A UI writer should not temporarily write a partial config shape that the gateway then treats as a clobber.
  • Auto-restore should remain a last-resort safety net, not part of normal UI config update flow.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING