openclaw - 💡(How to fix) Fix JSON file reads should retry on transient race conditions [1 pull requests]

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…

Error Message

  1. Observe error: JsonFileReadError: Failed to read JSON file: /home/simon/.openclaw/devices/paired.json
  • Error propagates as gateway failure
  • #71873 — Silent read error on paired.json

Fix Action

Fixed

Code Example

// Pseudocode
async function readJsonFile(path, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fs.readJson(path);
    } catch (err) {
      if (err.message.includes('File changed during read') && i < maxRetries - 1) {
        await sleep(50 * Math.pow(2, i)); // exponential backoff
        continue;
      }
      throw err;
    }
  }
}
RAW_BUFFERClick to expand / collapse

Bug Description

JsonFileReadError: File changed during read occurs when paired.json is rewritten while another component is reading it. This is a transient race condition that should be handled gracefully rather than causing gateway failures.

Steps to Reproduce

  1. Have multiple gateway clients active (Discord, Control UI, CLI)
  2. Trigger a paired.json rewrite (e.g., open openclaw logs --follow)
  3. Another component reads paired.json during the temp-file + rename operation
  4. Observe error: JsonFileReadError: Failed to read JSON file: /home/simon/.openclaw/devices/paired.json
  5. Followed by: gateway closed (1000)

Expected Behavior

JSON file reads should be resilient to concurrent rewrites:

  • Retry on File changed during read (max 3 attempts, 50ms backoff)
  • Distinguish between "file changed" (retry) and "file corrupted" (fail)
  • Do not surface transient read races as gateway failures

Actual Behavior

  • Single read attempt fails immediately
  • Error propagates as gateway failure
  • Triggers websocket reconnect
  • Reconnect may trigger another paired.json rewrite → amplification loop

Environment

  • OpenClaw version: 2026.5.12
  • File write pattern: temp-file + fsync + rename (atomic)
  • Read pattern: single attempt, no retry

Related Issues

  • #81169 — paired.json stale entries and rewrite frequency
  • #83656 — openclaw logs --follow registers as paired device
  • #71873 — Silent read error on paired.json

Recommendation

Implement bounded retry logic for JSON file reads:

// Pseudocode
async function readJsonFile(path, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fs.readJson(path);
    } catch (err) {
      if (err.message.includes('File changed during read') && i < maxRetries - 1) {
        await sleep(50 * Math.pow(2, i)); // exponential backoff
        continue;
      }
      throw err;
    }
  }
}

This is a standard pattern for atomic file operations and should be applied to all JSON config reads, not just paired.json.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix JSON file reads should retry on transient race conditions [1 pull requests]