openclaw - 💡(How to fix) Fix Cross-version image upgrade: bundled-runtime-mirror EACCES on stale symlink in plugin-runtime-deps/ [3 comments, 3 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#75108Fetched 2026-05-01 05:38:07
View on GitHub
Comments
3
Participants
3
Timeline
12
Reactions
2
Author
Timeline (top)
commented ×3mentioned ×3subscribed ×3cross-referenced ×2

When an OpenClaw container is upgraded to a new image version, gateway crash-loops with EACCES: permission denied, copyfile … .openclaw-mirror-…tmp because the bundled-runtime-mirror copies through stale symlinks pointing at the read-only image layer.

Error Message

{
  errno: -13,
  code: 'EACCES',
  syscall: 'copyfile',
  path: '/opt/openclaw/dist/agents/auth-profiles.runtime.js',
  dest: '/home/agent/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-d2ac19f1349f/dist/agents/.openclaw-mirror-1-…-auth-profiles.runtime.js.tmp'
}
[openclaw] Failed to start CLI: Error: EACCES: permission denied, copyfile '…' -> '…'
    at Object.copyFileSync (node:fs:3105:11)
    at copyBundledRuntimeMirrorFileAtomic (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:142:6)
    at copyBundledPluginRuntimeRoot (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:65:3)
    at tracePluginLifecyclePhase.pluginId (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:36:3)

Root Cause

The destination directory at plugin-runtime-deps/openclaw-2026.4.27-…/dist/agents/ is a symlink pointing to /opt/openclaw/dist/agents/ — left over from the previous OpenClaw version's mirror initialization. When copyBundledRuntimeMirrorFileAtomic writes a .tmp file to that path, the kernel resolves the symlink and tries to write into the image's read-only layer. EACCES.

Confirmed: ``` $ ls -l /home/agent/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-d2ac19f1349f/dist/agents lrwxrwxrwx 1 1001 1001 25 Apr 28 13:39 dist/agents -> /opt/openclaw/dist/agents ```

Many other entries under dist/ are also symlinks (auto-reply, media-understanding, plus dozens of *.js files), so removing just dist/agents produces the same crash on the next file.

Fix Action

Workaround

Wipe the entire plugin-runtime-deps/ directory before container recreate. OpenClaw rebuilds it cleanly from scratch on first boot. Costs ~30-60s extra boot per tenant.

Code Example

{
  errno: -13,
  code: 'EACCES',
  syscall: 'copyfile',
  path: '/opt/openclaw/dist/agents/auth-profiles.runtime.js',
  dest: '/home/agent/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-d2ac19f1349f/dist/agents/.openclaw-mirror-1-…-auth-profiles.runtime.js.tmp'
}
[openclaw] Failed to start CLI: Error: EACCES: permission denied, copyfile '…' -> '…'
    at Object.copyFileSync (node:fs:3105:11)
    at copyBundledRuntimeMirrorFileAtomic (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:142:6)
    at copyBundledPluginRuntimeRoot (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:65:3)
    at tracePluginLifecyclePhase.pluginId (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:36:3)
RAW_BUFFERClick to expand / collapse

Summary

When an OpenClaw container is upgraded to a new image version, gateway crash-loops with EACCES: permission denied, copyfile … .openclaw-mirror-…tmp because the bundled-runtime-mirror copies through stale symlinks pointing at the read-only image layer.

Repro

Multi-tenant container deployment (badclaw fleet on Hetzner). Tenants on badclaw-openclaw:main-20260428-patched (OpenClaw v2026.4.26) recreated onto badclaw-openclaw:2026.4.27-patched-claude (OpenClaw v2026.4.27). The volume /home/agent/.openclaw is bind-mounted from the host, so it preserves plugin-runtime-deps/ across recreates.

Result: 2 of 3 tenants crash-looped (138 and 32 restarts before manual intervention). The 3rd tenant whose volume was effectively empty pre-upgrade booted cleanly.

Stack trace

{
  errno: -13,
  code: 'EACCES',
  syscall: 'copyfile',
  path: '/opt/openclaw/dist/agents/auth-profiles.runtime.js',
  dest: '/home/agent/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-d2ac19f1349f/dist/agents/.openclaw-mirror-1-…-auth-profiles.runtime.js.tmp'
}
[openclaw] Failed to start CLI: Error: EACCES: permission denied, copyfile '…' -> '…'
    at Object.copyFileSync (node:fs:3105:11)
    at copyBundledRuntimeMirrorFileAtomic (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:142:6)
    at copyBundledPluginRuntimeRoot (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:65:3)
    at tracePluginLifecyclePhase.pluginId (file:///opt/openclaw/dist/bundled-runtime-root-Bvrq1R9V.js:36:3)

Root cause

The destination directory at plugin-runtime-deps/openclaw-2026.4.27-…/dist/agents/ is a symlink pointing to /opt/openclaw/dist/agents/ — left over from the previous OpenClaw version's mirror initialization. When copyBundledRuntimeMirrorFileAtomic writes a .tmp file to that path, the kernel resolves the symlink and tries to write into the image's read-only layer. EACCES.

Confirmed: ``` $ ls -l /home/agent/.openclaw/plugin-runtime-deps/openclaw-2026.4.27-d2ac19f1349f/dist/agents lrwxrwxrwx 1 1001 1001 25 Apr 28 13:39 dist/agents -> /opt/openclaw/dist/agents ```

Many other entries under dist/ are also symlinks (auto-reply, media-understanding, plus dozens of *.js files), so removing just dist/agents produces the same crash on the next file.

Workaround

Wipe the entire plugin-runtime-deps/ directory before container recreate. OpenClaw rebuilds it cleanly from scratch on first boot. Costs ~30-60s extra boot per tenant.

Suggested fix

In bundled-runtime-root.js#copyBundledRuntimeMirrorFileAtomic (or equivalent in the newer source), detect when the destination's parent directory is a symlink and `unlink + mkdir` before writing. Equivalent: when initializing the mirror tree for a new OpenClaw version, never reuse symlink entries from a previous version's tree — always materialize as real dirs.

Environment

  • Host: Hetzner CPX41, Ubuntu 24.04, Docker (overlay2 storage driver)
  • Bind mount: ./tenants/<name>/openclaw:/home/agent/.openclaw
  • Container UID: 1001:1001 (agent), running unprivileged
  • OpenClaw versions involved: source v2026.4.26 → v2026.4.27, both running from a badclaw- prefixed branch with one out-of-tree patch (feat(bluebubbles): add reply-context API fallback)

extent analysis

TL;DR

The most likely fix is to wipe the entire plugin-runtime-deps/ directory before container recreate or modify the copyBundledRuntimeMirrorFileAtomic function to handle symlinks.

Guidance

  • Verify the presence of symlinks in the plugin-runtime-deps/ directory using ls -l command.
  • Consider wiping the entire plugin-runtime-deps/ directory before container recreate as a temporary workaround.
  • To fix the issue permanently, modify the copyBundledRuntimeMirrorFileAtomic function to detect and handle symlinks by unlinking and remaking the directory.
  • Ensure the container has the necessary permissions to write to the plugin-runtime-deps/ directory.

Example

No code example is provided as the issue does not contain sufficient information about the copyBundledRuntimeMirrorFileAtomic function implementation.

Notes

The suggested fix requires modifying the OpenClaw source code, which may not be feasible for all users. The workaround of wiping the plugin-runtime-deps/ directory may incur a temporary performance penalty.

Recommendation

Apply the workaround of wiping the entire plugin-runtime-deps/ directory before container recreate, as it is a simpler and more immediate solution. This will allow the OpenClaw container to boot cleanly, albeit with a slight performance penalty.

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 Cross-version image upgrade: bundled-runtime-mirror EACCES on stale symlink in plugin-runtime-deps/ [3 comments, 3 participants]