Plugin install fails with EXDEV on cross-device /home and /tmp

Resolved 💬 3 comments Opened Feb 10, 2026 by NoobyNull Closed Feb 13, 2026

Bug Description

Plugin installation fails with EXDEV: cross-device link not permitted when ~/.claude and /tmp are on different filesystems (common on Linux with btrfs subvolumes, separate partitions, or tmpfs-backed /tmp).

Error

Error: Failed to install: EXDEV: cross-device link not permitted, rename '/home/<user>/.claude/plugins/cache/laminark' -> '/tmp/claude-plugin-temp-1770702418603'

Root Cause

The plugin installer uses fs.rename() to move files between ~/.claude/plugins/cache/ and a temp path in /tmp. fs.rename() is a wrapper around the POSIX rename(2) syscall, which cannot move files across filesystem boundaries.

Environment

  • OS: Arch Linux (CachyOS kernel 6.18.8-3)
  • Filesystems: /home on nvme (/dev/nvme3n1p2), /tmp on tmpfs
  • This is a very common Linux setup — many distros mount /tmp as tmpfs by default (systemd's tmp.mount)

Suggested Fix

Replace the bare fs.rename() with a cross-device-safe move:

  • Option A: Use fs-extra's move() which handles EXDEV automatically with copy+unlink fallback
  • Option B: Catch EXDEV and fall back to fs.copyFile() + fs.unlink()
  • Option C: Use os.tmpdir() only as a fallback, and prefer creating temp directories on the same filesystem as the target (e.g., ~/.claude/tmp/)

Workaround

Setting TMPDIR to a path on the same filesystem as ~/.claude before launching Claude Code:

export TMPDIR="$HOME/.local/tmp"
mkdir -p "$TMPDIR"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗