Summary
restoreConfigFromBase crashes with ENOENT: no such file or directory, statx '<path>' when the snapshotted PR directory contains a symlink whose target lives outside the SENSITIVE_PATHS set (e.g. .claude/skills/<name> → ../../.agents/skills/<name>).
This is a regression introduced on 2026-05-14 by the combination of:
The earlier fix #1186 closed #1187 / #1220 / #1311, but those issues were all about symlinks whose target is itself a SENSITIVE_PATH entry (e.g. CLAUDE.md → AGENTS.md). The fix does not cover the case here: the symlink lives inside .claude/ but points to a sibling directory (.agents/) that is NOT in SENSITIVE_PATHS, so cpSync with dereference: true follows the symlink and then statx fails the moment it traverses out of the snapshot tree.
Repro
Workflow:
- uses: anthropics/claude-code-action@v1
Repo layout:
.claude/skills/shadcn -> ../../.agents/skills/shadcn # symlink (in repo, tracked as mode 120000)
.agents/skills/shadcn/ # real directory (tracked, present after actions/checkout@v5)
Note: the symlink target IS present on disk after checkout — .agents/ is a regular tracked directory in the repo. The failure is not "dangling symlink".
Failure log
Restoring .claude, .mcp.json, .claude.json, .gitmodules, .ripgreprc, CLAUDE.md, CLAUDE.local.md, .husky from origin/master (PR head is untrusted)
##[error]Action failed with error: ENOENT: no such file or directory, statx '.claude/skills/shadcn'
Confirmed timeline
- Last green run: action SHA
86eb26bf0139bdd75acd15ea5f00f45ee0a284c2, runner bun-version: 1.3.6, 2026-05-14 18:02 UTC.
- First red run (same workflow, same repo, same symlink): action SHA
51ea8ea73a139f2a74ff649e3092c25a904aed7e, runner bun-version: 1.3.14, 2026-05-15 13:28 UTC.
- Workflow file and repo symlink unchanged across that window.
- Every PR in our repo has failed identically since 5/15 (multiple branches and authors).
Hypothesis on the failure mode
In src/github/operations/restore-config.ts:
for (const p of SENSITIVE_PATHS) {
if (existsSync(p)) {
cpSync(p, `.claude-pr/${p}`, { recursive: true, dereference: true });
}
}
When cpSync recurses into .claude/ and reaches .claude/skills/shadcn, dereference: true makes it follow the symlink and statx the target. Bun 1.3.14 appears to throw on this where 1.3.6 tolerated it — possibly stricter symlink/statx semantics, or an interaction with how Bun materializes the dereferenced path during recursive copy.
(We have not isolated whether the immediate cause is Bun 1.3.14 itself or the dereference: true + Bun 1.3.14 combination, but reverting either piece to the pre-2026-05-14 state restores green CI.)
Suggested directions
- Skip individual entries whose resolved target lies outside
SENSITIVE_PATHS, or
- Wrap each per-entry
cpSync in a try/catch that warns and falls back to snapshotting the link as a link (not its content), or
- Reproduce against Bun 1.3.14 specifically and report upstream if this is a Bun regression.
Workaround users can apply now
Pin the action to the last good SHA in their workflow:
uses: anthropics/claude-code-action@86eb26bf0139bdd75acd15ea5f00f45ee0a284c2 # last v1 before 2026-05-14 22:56 UTC
This avoids both the dereference: true change and Bun 1.3.14. Confirmed green again with this pin.
Affected scope
Not a single-repo issue — this hits any repo whose .claude/ includes a symlink pointing outside SENSITIVE_PATHS (a reasonable pattern for sharing prompts/skills between two top-level directories like .claude/ and .agents/).
Summary
restoreConfigFromBasecrashes withENOENT: no such file or directory, statx '<path>'when the snapshotted PR directory contains a symlink whose target lives outside theSENSITIVE_PATHSset (e.g..claude/skills/<name> → ../../.agents/skills/<name>).This is a regression introduced on 2026-05-14 by the combination of:
.claude-pr/", merged 22:36 UTC) — addeddereference: trueto thecpSynccall.1.3.6to1.3.14in the samev1rollout (22:56 UTC, commit51ea8ea).The earlier fix #1186 closed #1187 / #1220 / #1311, but those issues were all about symlinks whose target is itself a SENSITIVE_PATH entry (e.g.
CLAUDE.md → AGENTS.md). The fix does not cover the case here: the symlink lives inside.claude/but points to a sibling directory (.agents/) that is NOT inSENSITIVE_PATHS, socpSyncwithdereference: truefollows the symlink and thenstatxfails the moment it traverses out of the snapshot tree.Repro
Workflow:
Repo layout:
Note: the symlink target IS present on disk after checkout —
.agents/is a regular tracked directory in the repo. The failure is not "dangling symlink".Failure log
Confirmed timeline
86eb26bf0139bdd75acd15ea5f00f45ee0a284c2, runnerbun-version: 1.3.6, 2026-05-14 18:02 UTC.51ea8ea73a139f2a74ff649e3092c25a904aed7e, runnerbun-version: 1.3.14, 2026-05-15 13:28 UTC.Hypothesis on the failure mode
In
src/github/operations/restore-config.ts:When
cpSyncrecurses into.claude/and reaches.claude/skills/shadcn,dereference: truemakes it follow the symlink andstatxthe target. Bun 1.3.14 appears to throw on this where 1.3.6 tolerated it — possibly stricter symlink/statx semantics, or an interaction with how Bun materializes the dereferenced path during recursive copy.(We have not isolated whether the immediate cause is Bun 1.3.14 itself or the
dereference: true+ Bun 1.3.14 combination, but reverting either piece to the pre-2026-05-14 state restores green CI.)Suggested directions
SENSITIVE_PATHS, orcpSyncin a try/catch that warns and falls back to snapshotting the link as a link (not its content), orWorkaround users can apply now
Pin the action to the last good SHA in their workflow:
This avoids both the
dereference: truechange and Bun 1.3.14. Confirmed green again with this pin.Affected scope
Not a single-repo issue — this hits any repo whose
.claude/includes a symlink pointing outsideSENSITIVE_PATHS(a reasonable pattern for sharing prompts/skills between two top-level directories like.claude/and.agents/).