openclaw - 💡(How to fix) Fix [Bug]: plugin mirror rebuilt on every plugin load [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#72933Fetched 2026-04-28 06:30:04
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×2closed ×1commented ×1

mirrorBundledPluginRuntimeRoot() rebuilds the plugin's mirror directory from scratch on every load, even when the source files have not changed. On my Pi 500 each channel reconnect or model-provider load translates to several hundred small files written to disk.

Root Cause

mirrorBundledPluginRuntimeRoot() rebuilds the plugin's mirror directory from scratch on every load, even when the source files have not changed. On my Pi 500 each channel reconnect or model-provider load translates to several hundred small files written to disk.

Code Example

copyBundledPluginRuntimeRoot(params.pluginRoot, stagedRoot);
fs.rmSync(mirrorRoot, { recursive: true, force: true });
fs.renameSync(stagedRoot, mirrorRoot);

---

2026-04-27T16:46:10 [whatsapp] Web connection closed (status 408). Retry 1/12 in 2.44s... (status=408 Request Time-out Connection was lost)

---

16:42:51 - 16:43:21 :   0 files
16:43:21 - 16:43:52 :   0 files
16:43:52 - 16:44:22 :   0 files
16:44:22 - 16:44:52 :   0 files
16:44:52 - 16:45:22 :   0 files
16:45:22 - 16:45:52 :   0 files
16:45:52 - 16:46:22 : 119 files
16:46:22 - 16:46:52 : 729 files

---

108 dist/extensions/discord/
 77 dist/extensions/whatsapp/
 49 dist/extensions/google/
 36 dist/extensions/openai/
 29 dist/extensions/qqbot/
 26 dist/extensions/xai/
 22 dist/extensions/minimax/
 21 dist/extensions/codex/
 21 dist/extensions/anthropic/
 20 dist/extensions/browser/
 15 dist/extensions/github-copilot/
 13 dist/extensions/openrouter/
 13 dist/extensions/mistral/
 13 dist/extensions/elevenlabs/
 12 dist/extensions/moonshot/

---

PID SYSCPU USRCPU RDELAY BDELAY  VGROW  RGROW  THR S CPUNR  CPU CMD
 190189  0.54s  9.76s  0.74s  0.00s   1.8M 101.4M   11 R     3 104% openclaw-gatew
 190837  0.82s  9.36s  0.66s  0.00s   1.8M   1.2M   15 R     1 102% openclaw-messa
RAW_BUFFERClick to expand / collapse

Bug type

Bug (mirrorBundledPluginRuntimeRoot rebuilds plugin tree on every load)

Beta release blocker

No

Summary

mirrorBundledPluginRuntimeRoot() rebuilds the plugin's mirror directory from scratch on every load, even when the source files have not changed. On my Pi 500 each channel reconnect or model-provider load translates to several hundred small files written to disk.

Steps to reproduce

  1. Run openclaw 2026.4.25
  2. Have at least two bundled channels enabled that go through reconnect occasionally (WhatsApp and Discord in my case)
  3. Leave the gateway running for 20-30 minutes
  4. Watch mtimes under ~/.openclaw/plugin-runtime-deps/<install-root>/dist/extensions/<plugin>/ and the gateway journal for channel reconnect events

Expected behaviour

If the mirror already matches the source there should be no rebuild step.

Actual behaviour

Each call to prepareBundledPluginRuntimeRoot() reaches mirrorBundledPluginRuntimeRoot(), which always runs:

copyBundledPluginRuntimeRoot(params.pluginRoot, stagedRoot);
fs.rmSync(mirrorRoot, { recursive: true, force: true });
fs.renameSync(stagedRoot, mirrorRoot);

copyBundledPluginRuntimeRoot() copies every file in the source plugin tree one at a time (skipping node_modules). For my install each plugin tree is in the tens to low hundreds of files. The full rebuild runs every time even when the source files have not changed.

A single channel reconnect triggers a rebuild across multiple bundled plugins, not just the channel that reconnected.

OpenClaw version

2026.4.25

Environment

Raspberry Pi 500 (Debian Trixie, aarch64). Gateway runs as a systemd user service. ~/.openclaw/ and ~/.npm-global/ both live on its one and only SD card.

Logs, screenshots, and evidence

WhatsApp 408 reconnect followed by a burst of file writes. Gateway started at 16:34, idle for ~12 minutes, then:

2026-04-27T16:46:10 [whatsapp] Web connection closed (status 408). Retry 1/12 in 2.44s... (status=408 Request Time-out Connection was lost)

Per-30s file rewrites under ~/.openclaw/plugin-runtime-deps/:

16:42:51 - 16:43:21 :   0 files
16:43:21 - 16:43:52 :   0 files
16:43:52 - 16:44:22 :   0 files
16:44:22 - 16:44:52 :   0 files
16:44:52 - 16:45:22 :   0 files
16:45:22 - 16:45:52 :   0 files
16:45:52 - 16:46:22 : 119 files
16:46:22 - 16:46:52 : 729 files

Per-plugin breakdown of the 848 files rewritten across that 60s window (top 15):

108 dist/extensions/discord/
 77 dist/extensions/whatsapp/
 49 dist/extensions/google/
 36 dist/extensions/openai/
 29 dist/extensions/qqbot/
 26 dist/extensions/xai/
 22 dist/extensions/minimax/
 21 dist/extensions/codex/
 21 dist/extensions/anthropic/
 20 dist/extensions/browser/
 15 dist/extensions/github-copilot/
 13 dist/extensions/openrouter/
 13 dist/extensions/mistral/
 13 dist/extensions/elevenlabs/
 12 dist/extensions/moonshot/

atop during the burst, both gateway processes running hot:

    PID SYSCPU USRCPU RDELAY BDELAY  VGROW  RGROW  THR S CPUNR  CPU CMD
 190189  0.54s  9.76s  0.74s  0.00s   1.8M 101.4M   11 R     3 104% openclaw-gatew
 190837  0.82s  9.36s  0.66s  0.00s   1.8M   1.2M   15 R     1 102% openclaw-messa

Impact and severity

Affected: on my Pi 500 with everything on SD card, a single WhatsApp 408 reconnect produces ~850 file writes (~30 MB) in ~60s. With WhatsApp's 30-minute idle reconnect this works out to ~1.4 GB/day of avoidable SD writes. During the burst the gateway is sometimes blocked on disk I/O, and Discord heartbeats can miss their window.

Severity: high (extra SD writes plus event-loop stalls during bursts)

Frequency: every channel reconnect or plugin load.

Consequence: SD wear, occasional event-loop stalls, missed Discord heartbeats on slower storage.

Additional information

I worked around this by pointing OPENCLAW_PLUGIN_STAGE_DIR at a ram disk (~2.2 GB tmpfs in my case, cleared on reboot).

extent analysis

TL;DR

The issue can be mitigated by optimizing the mirrorBundledPluginRuntimeRoot function to only rebuild the plugin tree when the source files have changed.

Guidance

  • Verify that the mirrorBundledPluginRuntimeRoot function is indeed the cause of the issue by monitoring the file writes and system resource usage during the reconnect events.
  • Consider implementing a check to see if the source files have changed before rebuilding the plugin tree, potentially using file timestamps or hashes to determine if a rebuild is necessary.
  • As a temporary workaround, using a ram disk for the OPENCLAW_PLUGIN_STAGE_DIR can help reduce the number of writes to the SD card.
  • Investigate the possibility of optimizing the copyBundledPluginRuntimeRoot function to only copy files that have changed, rather than rebuilding the entire tree.

Example

const fs = require('fs');

// Before rebuilding the plugin tree, check if the source files have changed
function mirrorBundledPluginRuntimeRoot(params) {
  const sourceFiles = fs.readdirSync(params.pluginRoot);
  const targetFiles = fs.readdirSync(mirrorRoot);

  // If the source files have not changed, do not rebuild the tree
  if (sourceFiles.every(file => targetFiles.includes(file))) {
    return;
  }

  // Rebuild the tree only if necessary
  copyBundledPluginRuntimeRoot(params.pluginRoot, stagedRoot);
  fs.rmSync(mirrorRoot, { recursive: true, force: true });
  fs.renameSync(stagedRoot, mirrorRoot);
}

Notes

The provided workaround using a ram disk may not be suitable for all environments, and a more permanent solution should be implemented to optimize the mirrorBundledPluginRuntimeRoot function.

Recommendation

Apply the workaround of using a ram disk for the OPENCLAW_PLUGIN_STAGE_DIR until a more permanent solution can be implemented to optimize the `

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 [Bug]: plugin mirror rebuilt on every plugin load [1 comments, 2 participants]