Verify latest release
pnpm version
No response
Which area(s) of pnpm are affected? (leave empty if unsure)
Package manager compatibility
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
Inside an unprivileged LXC container (user namespace, idmapped mounts) — e.g. a Proxmox LXC with unprivileged: 1, or rootless podman:
mkdir -p ws/packages/app && cd ws
printf 'packages:\n - "packages/*"\n' > pnpm-workspace.yaml
echo '{"name":"repro","version":"0.0.0","private":true,"packageManager":"pnpm@12.3.4"}' > package.json
echo '{"name":"app","version":"0.0.0","private":true}' > packages/app/package.json
npx pnpm@12.3.4 --filter app deploy /tmp/out --legacy
Fails on 12.3.4; the same host with pnpm 11.x succeeds. Also fails without --legacy. pnpm install in the same workspace succeeds.
Describe the Bug
pnpm deploy aborts in the "copy project files" phase with Operation not permitted (os error 1) at an arbitrary file (varies per run), e.g.:
× copy project files
╰─▶ failed to import "/…/packages/app/package.json" to
"/tmp/out_pacquet-stage_…/package.json_pacquet-stage_…": Operation not permitted (os error 1)
Diagnosis (probed empirically on the failing host):
Inside a user-namespace container the kernel rejects remap_file_range (the FICLONE path) with EPERM — by design for idmapped mounts — independent of filesystem:
| probe (same host) |
result |
| FICLONE, container process, ZFS→ZFS |
EPERM |
| FICLONE, container process, tmpfs→tmpfs (tmpfs cannot clone at all) |
EPERM — denial happens before any fs is consulted |
| FICLONE, container root |
EPERM |
| FICLONE, host process, same dataset |
works |
cp --reflink=auto in container |
OK (GNU cp falls back to copy) |
pnpm 12's Rust import strategy falls back on ENOTSUP (→hardlink) and EXDEV (→copy, sticky), but treats EPERM from the clone attempt as fatal — so deploy dies at whichever file the walk imports when the strategy attempts the clone.
A contrast that pinpoints it: pnpm install works in the same container — v12 changed store imports to hardlink-first on Linux, and store→workspace hardlinks are same-fs → they succeed. The deploy project-file importer, however, hits the clone.
--config.package-import-method=copy does not help: it governs store→node_modules imports, not the deploy project-file copy.
This makes pnpm deploy unusable in every user-namespace container (unprivileged LXC, rootless podman, CI sandboxes) — a fairly common production environment class.
Expected Behavior
A failed clone attempt (EPERM) should fall back to hardlink/copy just like ENOTSUP/EXDEV does — ideally probing once and permanently switching the strategy for the rest of the operation, as the EXDEV fallback already does.
Which Node.js version are you using?
v24.20.0
Which operating systems have you used?
If your OS is a Linux based, which one it is? (Include the version if relevant)
Debian 13 (trixie) inside an unprivileged LXC (Proxmox), host kernel 7.0.2-7-pve
Verify latest release
pnpm version
No response
Which area(s) of pnpm are affected? (leave empty if unsure)
Package manager compatibility
Link to the code that reproduces this issue or a replay of the bug
No response
Reproduction steps
Inside an unprivileged LXC container (user namespace, idmapped mounts) — e.g. a Proxmox LXC with
unprivileged: 1, or rootless podman:mkdir -p ws/packages/app && cd ws
printf 'packages:\n - "packages/*"\n' > pnpm-workspace.yaml
echo '{"name":"repro","version":"0.0.0","private":true,"packageManager":"pnpm@12.3.4"}' > package.json
echo '{"name":"app","version":"0.0.0","private":true}' > packages/app/package.json
npx pnpm@12.3.4 --filter app deploy /tmp/out --legacy
Fails on 12.3.4; the same host with pnpm 11.x succeeds. Also fails without
--legacy.pnpm installin the same workspace succeeds.Describe the Bug
pnpm deployaborts in the "copy project files" phase withOperation not permitted (os error 1)at an arbitrary file (varies per run), e.g.:× copy project files
╰─▶ failed to import "/…/packages/app/package.json" to
"/tmp/out_pacquet-stage_…/package.json_pacquet-stage_…": Operation not permitted (os error 1)
Diagnosis (probed empirically on the failing host):
Inside a user-namespace container the kernel rejects
remap_file_range(the FICLONE path) with EPERM — by design for idmapped mounts — independent of filesystem:cp --reflink=autoin containerpnpm 12's Rust import strategy falls back on ENOTSUP (→hardlink) and EXDEV (→copy, sticky), but treats EPERM from the clone attempt as fatal — so
deploydies at whichever file the walk imports when the strategy attempts the clone.A contrast that pinpoints it:
pnpm installworks in the same container — v12 changed store imports to hardlink-first on Linux, and store→workspace hardlinks are same-fs → they succeed. The deploy project-file importer, however, hits the clone.--config.package-import-method=copydoes not help: it governs store→node_modulesimports, not the deploy project-file copy.This makes
pnpm deployunusable in every user-namespace container (unprivileged LXC, rootless podman, CI sandboxes) — a fairly common production environment class.Expected Behavior
A failed clone attempt (EPERM) should fall back to hardlink/copy just like ENOTSUP/EXDEV does — ideally probing once and permanently switching the strategy for the rest of the operation, as the EXDEV fallback already does.
Which Node.js version are you using?
v24.20.0
Which operating systems have you used?
If your OS is a Linux based, which one it is? (Include the version if relevant)
Debian 13 (trixie) inside an unprivileged LXC (Proxmox), host kernel 7.0.2-7-pve