Skip to content

Commit 66ded93

Browse files
baxyzclaude
andcommitted
fix(pnpm-store): 🐛 fix silent failures in guard script ownership handling
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>
1 parent 1a11c83 commit 66ded93

2 files changed

Lines changed: 13 additions & 5 deletions

File tree

src/pnpm-store/devcontainer-feature.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "pnpm-store",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"name": "pnpm Store (shared)",
55
"description": "Shares a single pnpm content-addressable store across every repo and across rebuilds via a Docker named volume, so no stray .pnpm-store folders pollute your repos. Zero-config and autonomous: the volume is created automatically, with no host directory to pre-create.",
66
"documentationURL": "https://github.com/helpers4/devcontainer/tree/main/src/pnpm-store",

src/pnpm-store/install.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ echo " ✅ Wrote store-dir to ${NPMRC}"
8282
# pnpm cannot create the store directory as a non-root user.
8383
# The named volume declared in devcontainer-feature.json shadows this directory
8484
# at container start — that's intentional.
85-
mkdir -p "${STORE_DIR}"
85+
mkdir -p "${STORE_DIR}" || true
8686
if [ "${USERNAME}" != "root" ]; then
8787
chown "${USERNAME}:${USER_GROUP}" "${STORE_DIR}" 2>/dev/null || true
8888
fi
@@ -121,9 +121,17 @@ fi
121121
# Named volumes are created root-owned; hand the store to the current user so
122122
# pnpm can write to it. Only chown when needed (recursive chown is expensive on
123123
# a populated store shared across rebuilds).
124-
store_owner="$(stat -c '%u' "${STORE_DIR}" 2>/dev/null || echo '')"
125-
if [ -n "${store_owner}" ] && [ "${store_owner}" != "$(id -u)" ] && command -v sudo >/dev/null 2>&1; then
126-
sudo chown -R "$(id -u):$(id -g)" "${STORE_DIR}" 2>/dev/null || true
124+
# stat failure (NFS root-squash, overlay FS) is treated as "unknown" — attempt
125+
# chown anyway rather than silently skipping it.
126+
store_owner="$(stat -c '%u' "${STORE_DIR}" 2>/dev/null || echo 'unknown')"
127+
if [ "${store_owner}" != "$(id -u)" ]; then
128+
if command -v sudo >/dev/null 2>&1; then
129+
if ! sudo chown -R "$(id -u):$(id -g)" "${STORE_DIR}"; then
130+
echo "⚠️ pnpm-store: chown failed — pnpm may not be able to write to the store"
131+
fi
132+
else
133+
echo "⚠️ pnpm-store: store is owned by uid ${store_owner} and sudo is unavailable; pnpm writes will fail (EACCES)"
134+
fi
127135
fi
128136
129137
# Confirm pnpm picked up the configured store, when available.

0 commit comments

Comments
 (0)