Conversation
…atures mkdir STORE_DIR during the Docker image build (as root) so any pnpm invocation by a later feature (e.g. vite-plus) can use the configured store-dir path. Without this, /workspaces/.pnpm-store is written to ~/.npmrc but /workspaces doesn't exist yet at build time, causing pnpm to fail with 'Failed to install dependencies'. The named volume declared in devcontainer-feature.json shadows this empty directory at container start, so pnpm uses the persistent volume at runtime. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
✅ PR Validation Passed
📋 Pipeline Status
🤖 Generated by @helpers4 CI • 2026-06-01 |
| # pnpm cannot create the store directory as a non-root user. | ||
| # The named volume declared in devcontainer-feature.json shadows this directory | ||
| # at container start — that's intentional. | ||
| mkdir -p "${STORE_DIR}" |
There was a problem hiding this comment.
Altitude: this mkdir is a bandaid on a build-time/runtime mismatch
The root cause is that store-dir=/workspaces/.pnpm-store is written to ~/.npmrc at image-build time, but the path only exists at container start (after the named volume mounts). This mkdir patches the symptom so later build-time pnpm invocations (e.g. vite-plus) do not crash.
A deeper fix would defer the ~/.npmrc write to postCreateCommand — pnpm is not invoked at build time by this feature itself, so there is no need to configure it during the build. The named volume would then be the source of truth from the start.
That is a more invasive change; keeping the mkdir is a valid pragmatic call. If kept, it should at minimum add || true to prevent an image build abort on filesystems where root cannot create /workspaces (read-only overlay layers, unusual base images):
| mkdir -p "${STORE_DIR}" | |
| mkdir -p "${STORE_DIR}" || true | |
| if [ "${USERNAME}" != "root" ]; then | |
| chown "${USERNAME}:${USER_GROUP}" "${STORE_DIR}" 2>/dev/null || true | |
| fi | |
| echo " ✅ Created store directory at ${STORE_DIR}" |
Code review findings — guard script (pre-existing lines)These bugs exist in the guard script body (embedded in 🐛 Bug 1 — No-sudo path: store stays root-owned with no warning (CONFIRMED)# src/pnpm-store/install.sh, guard body ~line 125
if [ -n "${store_owner}" ] && [ "${store_owner}" != "$(id -u)" ] && command -v sudo >/dev/null 2>&1; then
sudo chown -R "$(id -u):$(id -g)" "${STORE_DIR}" 2>/dev/null || true
fiWhen Fix: if [ -n "${store_owner}" ] && [ "${store_owner}" != "$(id -u)" ]; then
if command -v sudo >/dev/null 2>&1; then
sudo chown -R "$(id -u):$(id -g)" "${STORE_DIR}" 2>/dev/null || echo "⚠️ pnpm-store: chown failed — pnpm may not be able to write to the store"
else
echo "⚠️ pnpm-store: store is root-owned and sudo is unavailable; pnpm writes will fail (EACCES)"
fi
fi🐛 Bug 2 —
|
…ling Three bugs in the postCreateCommand guard: - stat failure (NFS, overlay FS) returned empty store_owner, silently skipping chown and leaving the store root-owned with no diagnostic - sudo absent: the chown if-block was skipped entirely with no warning, causing pnpm EACCES on first write with nothing in the logs - sudo chown used 2>/dev/null || true, swallowing failures and printing a false success checkmark regardless of outcome Fix: treat stat failure as "unknown" (attempt chown anyway), split the sudo check to emit a warning when sudo is absent, and surface chown failures instead of swallowing them. Also add || true to the build-time mkdir -p to prevent aborting the image build on unusual filesystems where root cannot create /workspaces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Problem
install.shwritesstore-dir=/workspaces/.pnpm-storeinto~/.npmrcduring the Docker image build. But/workspacesdoes not exist at build time (it's mounted later by the container runtime). Any subsequent pnpm invocation by a later feature — notably vite-plus — fails with:because pnpm tries to create
/workspaces/.pnpm-storeas a non-root user and cannot.Fix
Add
mkdir -p "${STORE_DIR}"(as root) ininstall.sh, right after writing to~/.npmrc. This ensures the directory exists during the Docker build so pnpm can use the configured path immediately.The named volume declared in
devcontainer-feature.jsonshadows this empty directory at container start — that's intentional. The persistent volume is used at runtime; the image-layer directory is just a placeholder to keep the build working.Changes
src/pnpm-store/install.sh: createSTORE_DIRduring build, chown to remote usersrc/pnpm-store/devcontainer-feature.json: bump to v1.0.2Related
Supersedes / resolves the same root cause as #32.