From 6bcc2fe20778bd5aa9e6c12f76559167e720a523 Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Thu, 28 May 2026 17:07:15 +0100 Subject: [PATCH] fix(devcontainer): clean stale plugin/skill symlinks from prior design before writes A user upgrading from Option B (read-only host stage + symlinks) to the current hybrid RW-bind topology hit EROFS in post-create.sh when the plugin registry path-translator tried to write `/home/node/.claude/plugins/known_marketplaces.json`. The named volume still carried `/home/node/.claude/plugins -> /host/.claude/plugins` (Option B's symlink). The new design's sub-path bind mounts at `plugins/marketplaces` and `plugins/cache` overlay through the symlink, but writes to the parent dir itself resolve via the symlink to the RO host stage and fail. Drop any leftover symlinks at known target paths early in step 2 so the mkdir/writes that follow land in the volume. --- .devcontainer/post-create.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 8aa47c270..c571ce63a 100644 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -30,6 +30,22 @@ sudo chown -R node:node \ /commandhistory echo "[post-create] 2/7: sync AI CLI credentials + identity from host" +# Defensive cleanup for users upgrading from an earlier devcontainer +# design (Option B) where these paths were symlinks into the read-only +# host stage (e.g. /home/node/.claude/plugins -> /host/.claude/plugins). +# The current RW-bind topology overlays sub-paths but not the parent +# symlink itself, so writes to e.g. /home/node/.claude/plugins/known_marketplaces.json +# would resolve through the stale symlink to a read-only host file and +# EROFS. Drop the symlinks; mkdir -p below recreates them as real +# directories in the named volume. +for p in plugins skills agents memory commands; do + [ -L "/home/node/.claude/$p" ] && rm "/home/node/.claude/$p" +done +for p in config.toml memories skills; do + [ -L "/home/node/.codex/$p" ] && rm "/home/node/.codex/$p" +done +mkdir -p /home/node/.claude/plugins + # Plugins, skills, agents, memory, commands, settings.json, $HOME/.claude.json, # Codex config.toml/memories/skills are all RW bind-mounted directly from # host in devcontainer.json — they live on host and reads/writes go