{"version":"2.1.216","anchor":"worktree-safety-full-path-component-symlink-checks","canonical_anchor":"worktree-safety-full-path-component-symlink-checks","heading":"Worktree Safety: Full Path-Component Symlink Checks","tier":null,"area":null,"scope":null,"heads_up":null,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.216\/e\/worktree-safety-full-path-component-symlink-checks","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.216","markdown":"### Worktree Safety: Full Path-Component Symlink Checks\n\n**What**\n\nThe worktree removal and creation code now walks each directory component in a path without following symlinks, refusing to write into or remove a directory if any ancestor is a symlink (`O_NOFOLLOW` at every level). Rootless worktrees (agent directories that lost their git root) are now handled with a dedicated safe-remove path.\n\n**Details**\n\n- New `assertDirChainReal` function raises `ELOOP`\/`ENOTDIR` at the first symlinked component\n- `removeAgentWorktree` now handles the rootless case (no git root) separately: verifies the directory is inside `.claude\/worktrees\/`, is not a git repo, and requires an explicit `job_delete_force` source if the directory has any files\n- Hook-managed worktrees check for symlinks in the stored worktree path before invoking the remove hook\n- Error messages distinguish: \"stored worktree path is a symlink\", \"a component of the stored worktree path is a symlink\", \"path could not be verified \u2014 its resolution changed while being checked\"\n\n**Evidence**\n\nPath verifier (search for `\"assertDirChainReal: dir must be strictly inside base\"` or `\"Refusing to write under symlinked or non-directory path\"`). Rootless remove (search for `\"Removed agent worktree with no git root at:\"`)."}