Summary
anthropics/claude-code-action@v1 fails during its Restoring … from origin/main (PR head is untrusted) step with an ENOENT from statx on .claude/CLAUDE.md, in a repo where that path is a git symlink (mode 120000) whose target exists.
Repro
In a repo:
.claude/CLAUDE.md is a git symlink → ../AGENTS.md
AGENTS.md (real file) exists at the repo root
CLAUDE.md (root) is a git symlink → AGENTS.md
Both symlinks are well-formed on origin/main:
$ git ls-tree origin/main .claude/CLAUDE.md
120000 blob 6afa5602… .claude/CLAUDE.md
$ git show origin/main:.claude/CLAUDE.md
../AGENTS.md
$ git ls-tree origin/main AGENTS.md
100644 blob 0fd5e530… AGENTS.md
Workflow invocation is a vanilla anthropics/claude-code-action@v1:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: \${{ secrets.ANTHROPIC_API_KEY }}
use_sticky_comment: true
show_full_output: true
claude_args: |
--max-budget-usd 5
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash,Read,Glob,Grep"
--disallowedTools "Edit,Write,NotebookEdit"
prompt: |
REPO: \${{ github.repository }}
PR NUMBER: \${{ github.event.pull_request.number }}
Read and follow the instructions in .claude/REVIEW.md
Runs on ubuntu-24.04. actions/checkout@v4 with fetch-depth: 1 immediately before.
Failing log (truncated to relevant lines)
Installing Claude Code native build 2.1.169...
✔ Claude Code successfully installed!
Version: 2.1.169
Restoring .claude, .mcp.json, .claude.json, .gitmodules, .ripgreprc,
CLAUDE.md, CLAUDE.local.md, .husky from origin/main (PR head is untrusted)
##[error]Action failed with error: ENOENT: no such file or directory,
statx '.claude/CLAUDE.md'
Internal error: directory mismatch for directory
"/home/runner/work/_actions/anthropics/claude-code-action/v1/tsconfig.json",
fd 4. You don't need to do anything, but this indicates a bug.
##[error]Process completed with exit code 1.
…
No buffered inline comments
Diagnosis (speculative)
statx follows symlinks by default. The error pattern looks like the restore step is writing the symlink blob contents (the literal string ../AGENTS.md) as a regular file at .claude/CLAUDE.md, rather than recreating the symlink — and then a later step calls statx and ENOENTs because the path resolved through that "file" isn't a real path lookup.
Either:
- The git operation used to restore from
origin/main doesn't preserve symlink mode (120000), or
- Some later code path calls
fs.readFile / fs.statSync after the restore but a step in between converts the symlink to a text file.
The fact that the same action runs cleanly on PRs that don't touch .claude/ (we saw success on the action's own self-setup PR before this repo gained the symlinks pattern) supports the symlink-restore being the proximate cause.
Reproduces deterministically
Confirmed on two consecutive PR head SHAs in our repo: the action failed identically on the merge commit (f5c24dc…) and on a follow-up docs-only commit (10e6232…). Both failures show the same statx '.claude/CLAUDE.md' ENOENT immediately after Restoring … from origin/main.
Workaround for now
Marking the check as advisory in branch protection. Not converting the symlinks (single-source-of-truth AGENTS.md is intentional) and not vendoring a copy.
Action version
anthropics/claude-code-action@v1 resolved via the v1 tag at the time of the runs above (timestamps 2026-06-08T23:50Z and 2026-06-09T17:03Z UTC).
Summary
anthropics/claude-code-action@v1fails during itsRestoring … from origin/main (PR head is untrusted)step with anENOENTfromstatxon.claude/CLAUDE.md, in a repo where that path is a git symlink (mode120000) whose target exists.Repro
In a repo:
.claude/CLAUDE.mdis a git symlink →../AGENTS.mdAGENTS.md(real file) exists at the repo rootCLAUDE.md(root) is a git symlink →AGENTS.mdBoth symlinks are well-formed on
origin/main:Workflow invocation is a vanilla
anthropics/claude-code-action@v1:Runs on
ubuntu-24.04.actions/checkout@v4withfetch-depth: 1immediately before.Failing log (truncated to relevant lines)
Diagnosis (speculative)
statxfollows symlinks by default. The error pattern looks like the restore step is writing the symlink blob contents (the literal string../AGENTS.md) as a regular file at.claude/CLAUDE.md, rather than recreating the symlink — and then a later step callsstatxand ENOENTs because the path resolved through that "file" isn't a real path lookup.Either:
origin/maindoesn't preserve symlink mode (120000), orfs.readFile/fs.statSyncafter the restore but a step in between converts the symlink to a text file.The fact that the same action runs cleanly on PRs that don't touch
.claude/(we saw success on the action's own self-setup PR before this repo gained the symlinks pattern) supports the symlink-restore being the proximate cause.Reproduces deterministically
Confirmed on two consecutive PR head SHAs in our repo: the action failed identically on the merge commit (
f5c24dc…) and on a follow-up docs-only commit (10e6232…). Both failures show the samestatx '.claude/CLAUDE.md'ENOENT immediately afterRestoring … from origin/main.Workaround for now
Marking the check as advisory in branch protection. Not converting the symlinks (single-source-of-truth
AGENTS.mdis intentional) and not vendoring a copy.Action version
anthropics/claude-code-action@v1resolved via thev1tag at the time of the runs above (timestamps 2026-06-08T23:50Z and 2026-06-09T17:03Z UTC).