Plugin install fails with EXDEV when /tmp is on different filesystem
Description
Plugin installation fails with EXDEV: cross-device link not permitted when /tmp is mounted on a different filesystem than ~/.claude/plugins/.
Error Message
Error: Failed to install: EXDEV: cross-device link not permitted, rename
'/home/user/.claude/plugins/cache/<plugin>' -> '/tmp/claude-plugin-temp-1768434350964'
Environment
- OS: openSUSE Tumbleweed (also affects Fedora, Arch, and other systemd-based distros)
- Claude Code version: Latest
- Filesystem layout:
/homeon/dev/nvme0n1p3(ext4/btrfs)/tmpontmpfs(RAM-based)
Root Cause
The plugin installer uses fs.rename() to move files from the plugin cache to a temp directory in /tmp. The rename() syscall fails with EXDEV when source and destination are on different filesystems.
This is a very common Linux configuration - most systemd-based distributions mount /tmp as tmpfs by default for performance and SSD longevity.
Suggested Fix
When rename() fails with EXDEV, fall back to copy + delete:
async function moveFile(src, dest) {
try {
await fs.rename(src, dest);
} catch (err) {
if (err.code === 'EXDEV') {
// Cross-device move: copy then delete
await fs.cp(src, dest, { recursive: true });
await fs.rm(src, { recursive: true });
} else {
throw err;
}
}
}
Alternatively, use a temp directory on the same filesystem as the plugin cache (e.g., ~/.claude/plugins/.tmp/).
Workaround
Users can work around this by setting TMPDIR:
TMPDIR=~/.claude/tmp claude
Reproduction Steps
- Have a system where
/tmpis on tmpfs (default on most modern Linux distros) - Run Claude Code
- Try to install any plugin (e.g.,
/plugin install <plugin>) - Observe the EXDEV error
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗