Skip to content

EXDEV: cross-device link error during git plugin install in Docker containers #99885

Description

@CarelvanHeerden

Summary

openclaw plugins install git:<repo> fails with EXDEV: cross-device link not permitted when /tmp and ~/.openclaw are on different filesystems, which is common in Docker containers with bind-mounted volumes.

Steps to Reproduce

  1. Run OpenClaw in Docker with ~/.openclaw on a bind-mounted volume (e.g., btrfs, NFS, or any non-overlayfs mount)
  2. Run: openclaw plugins install git:github.com/CarelvanHeerden/openclaw-okf
  3. Installation fails:
Cloning CarelvanHeerden/openclaw-okf...
Installing plugin dependencies with npm…
failed to replace managed git plugin repository: Error: EXDEV: cross-device link not permitted,
  rename '/tmp/openclaw-git-plugin-…/repo' -> '/home/node/.openclaw/git/…/repo'

Root Cause

The git install code in install-source-utils uses os.tmpdir() (= /tmp) as the staging root, then performs an atomic fs.rename() into ~/.openclaw/git/. When these paths are on different filesystems (overlay vs bind mount), rename() fails with EXDEV.

Suggested Fix

Catch EXDEV and fall back to recursive copy + unlink:

try {
  await fs.rename(src, dest);
} catch (err) {
  if (err.code === 'EXDEV') {
    await fs.cp(src, dest, { recursive: true });
    await fs.rm(src, { recursive: true, force: true });
  } else {
    throw err;
  }
}

Alternatively, use ~/.openclaw/tmp/ as the staging directory instead of os.tmpdir() so both paths are on the same filesystem.

Workaround

Set TMPDIR to a path on the same filesystem:

TMPDIR=/home/node/.openclaw/tmp openclaw plugins install git:<repo>

Environment

  • OpenClaw: tested on 2026.5.2 and 2026.6.10
  • Docker: Unraid (btrfs bind mounts), also reproduced on standard Docker setups
  • Affects: all git: plugin installs in containerised environments with bind-mounted state dirs

Metadata

Metadata

Assignees

Labels

P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.no-staleExclude from stale automation

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions