openclaw - 💡(How to fix) Fix readPageSummaries: no concurrency limit on fs.readFile, triggers EDEADLK on iCloud/FileProvider-backed vaults [1 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#68738Fetched 2026-04-19 15:08:08
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

Error Message

readPageSummaries in dist/cli-mPaKxVzJ.js (line 586) unbounded-parallel fs.readFiles every markdown page in the wiki vault via Promise.all(filePaths.map(readFile)). For vaults backed by iCloud Drive / macOS FileProvider (e.g. Obsidian-in-iCloud), this kernel-level parallel read burst can deadlock the provider and surface as Error: Unknown system error -11: Unknown system error -11, read (errno 11 = EDEADLK, "Resource deadlock avoided"). 4. Observe repeated memory sync failed (session-delta): Error: Unknown system error -11: Unknown system error -11, read in gateway logs.

  • On macOS Unknown system error -11 is EDEADLK (errno 11); not the more-famous EAGAIN (35). Deadlock, not retryable transient.

Fix Action

Workaround

Move vault out of iCloud to a local disk path (e.g. ~/.openclaw/wiki) and re-point plugins.entries.memory-wiki.config.vault.path. This avoids FileProvider entirely but breaks iCloud-based cross-device sync for users who want it.

Code Example

// dist source (illustrative — originals are minified)
import pLimit from "p-limit";
async function readPageSummaries(rootDir) {
  const filePaths = (await Promise.all(COMPILE_PAGE_GROUPS.map((group) =>
    collectMarkdownFiles(rootDir, group.dir)))).flat();
  const limit = pLimit(8);
  return (await Promise.all(filePaths.map((relativePath) => limit(async () => {
    const absolutePath = path.join(rootDir, relativePath);
    return toWikiPageSummary({
      absolutePath,
      relativePath,
      raw: await fs$1.readFile(absolutePath, "utf8"),
    });
  })))).flatMap((page) => page ? [page] : []).toSorted((a, b) => a.title.localeCompare(b.title));
}
RAW_BUFFERClick to expand / collapse

Problem

readPageSummaries in dist/cli-mPaKxVzJ.js (line 586) unbounded-parallel fs.readFiles every markdown page in the wiki vault via Promise.all(filePaths.map(readFile)). For vaults backed by iCloud Drive / macOS FileProvider (e.g. Obsidian-in-iCloud), this kernel-level parallel read burst can deadlock the provider and surface as Error: Unknown system error -11: Unknown system error -11, read (errno 11 = EDEADLK, "Resource deadlock avoided").

Symptom: openclaw wiki ingest / openclaw wiki compile either hangs forever or fails with partial reads. When reads "succeed" under stress the content can be zero-length, producing silent wiki corruption.

Reproduction

  1. Put a memory-wiki vault in iCloud (vaultMode: bridge, vault path inside iCloudmdobsidian).
  2. Grow it to 150+ pages.
  3. Run openclaw wiki compile (or any flow that calls readPageSummaries).
  4. Observe repeated memory sync failed (session-delta): Error: Unknown system error -11: Unknown system error -11, read in gateway logs.
  5. fs.readFile fans out on 150+ files; iCloud FileProvider serializes reads and deadlocks under burst.

Secondary repro path (external): rsync / ditto / cat / redirected cp on the same directory reproduce EDEADLK in user space, confirming the issue is file-system-side rather than OpenClaw-specific — but OpenClaw is the one triggering the pathological pattern.

Proposed Fix

Cap concurrency at a small constant (e.g. 8) using p-limit or equivalent:

// dist source (illustrative — originals are minified)
import pLimit from "p-limit";
async function readPageSummaries(rootDir) {
  const filePaths = (await Promise.all(COMPILE_PAGE_GROUPS.map((group) =>
    collectMarkdownFiles(rootDir, group.dir)))).flat();
  const limit = pLimit(8);
  return (await Promise.all(filePaths.map((relativePath) => limit(async () => {
    const absolutePath = path.join(rootDir, relativePath);
    return toWikiPageSummary({
      absolutePath,
      relativePath,
      raw: await fs$1.readFile(absolutePath, "utf8"),
    });
  })))).flatMap((page) => page ? [page] : []).toSorted((a, b) => a.title.localeCompare(b.title));
}

Notes:

  • Concurrency of 8 is a conservative default; it survives iCloud FileProvider burstiness locally.
  • Same pattern is worth applying anywhere else in the wiki compile path that unbounded-Promise.alls file IO; readPageSummaries is just the most painful one.
  • Consider making the limit configurable (plugins.entries.memory-wiki.config.compile.concurrency) for users who know their vault is on a fast local disk.

Environment

  • OpenClaw 2026.4.15 (also repro on 2026.4.11, 2026.4.12)
  • macOS 26.4.1 (Tahoe) on Apple Silicon; same issue on 15.7.3 (Sequoia) before upgrade
  • Vault: Obsidian + iCloud sync, ~165 markdown pages
  • cli-mPaKxVzJ.js:586 readPageSummaries, cli-mPaKxVzJ.js:1011 compileMemoryWikiVault

Workaround

Move vault out of iCloud to a local disk path (e.g. ~/.openclaw/wiki) and re-point plugins.entries.memory-wiki.config.vault.path. This avoids FileProvider entirely but breaks iCloud-based cross-device sync for users who want it.

Related

  • On macOS Unknown system error -11 is EDEADLK (errno 11); not the more-famous EAGAIN (35). Deadlock, not retryable transient.

extent analysis

TL;DR

Limit the concurrency of fs.readFile operations in readPageSummaries to a small constant, such as 8, to prevent deadlocks with iCloud FileProvider.

Guidance

  • Apply the proposed fix by capping concurrency using p-limit or equivalent, as shown in the provided code snippet.
  • Consider making the concurrency limit configurable for users with fast local disks.
  • Identify and apply the same pattern to other parts of the wiki compile path that use unbounded Promise.all with file IO.
  • Verify the fix by running openclaw wiki compile and checking for the absence of Unknown system error -11 errors.

Example

The provided code snippet demonstrates how to cap concurrency using p-limit:

const limit = pLimit(8);
return (await Promise.all(filePaths.map((relativePath) => limit(async () => {
  // ...
}))));

Notes

  • The concurrency limit of 8 is a conservative default and may need to be adjusted for specific use cases.
  • This fix only addresses the issue with iCloud FileProvider and may not apply to other file systems or environments.

Recommendation

Apply the workaround by limiting concurrency, as it directly addresses the root cause of the issue and provides a reliable solution.

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 readPageSummaries: no concurrency limit on fs.readFile, triggers EDEADLK on iCloud/FileProvider-backed vaults [1 participants]