anthropics / anthropics/claude-code-action
`restoreConfigFromBase` crashes on dangling symlinks in `.claude/` directory
- Dominant language
- TypeScript
- Stars
- 8.9k
- Forks
- 2.1k
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 10
Description
**Describe the bug**
The `restoreConfigFromBase` step fails with `ENOENT` when `.claude/skills/` contains symlinks whose targets don't exist at the time the action runs. This started with Claude Code v2.1.142 — v2.1.141 on the same repo/branch worked fine.
Our project shares skill definitions across many repos via a package dependency. `.claude/skills/` contains symlinks into that dependency:
.claude/skills/check -> ../../vendor/package/.claude/skills/check
These resolve after dependency installation, but the action's restore step runs before that, so the symlink target is missing.
**To Reproduce**
1. Create a repo where `.claude/skills/` contains a symlink to a file outside the repo (e.g., inside `node_modules` or a similar dependency directory)
2. Do *not* install dependencies before the `claude-code-action` step
3. Open a PR
4. Action fails at the restore step:
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/check'
**Expected behavior**
The restore step should preserve symlinks as-is without following/resolving them. Dangling symlinks in `.claude/` should not cause a hard failure — they're expected to resolve later in the workflow.
**Workflow yml file**
```yaml
jobs:
review:
runs-on: [self-hosted, ubuntu-22.04]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 50
# Note: no dependency install step before claude-code-action
- uses: anthropics/claude-code-action@v1
with:
use_vertex: 'true'
prompt: "Review this PR"
```
API Provider
- GCP Vertex
Additional context
- The related fix in #1311 addresses a different ENOENT path (missing .claude-pr/ parent directory) and does not cover this case.
- Working: Claude Code v2.1.141 (runs before May 15)
- Broken: Claude Code v2.1.142+ (runs from May 15 onward)
- The cpSync call in restoreConfigFromBase appears to follow symlinks via statx. Using lstat-based copying or tolerating dangling symlinks would fix this.
Contributor guide
Research direction
Start at the restoreConfigFromBase step and inspect its cpSync-based handling of .claude/ paths, using the provided workflow and dangling-symlink reproduction as the first case to run. Verify that a missing symlink target no longer causes ENOENT and that the symlink remains available for later dependency installation, without regressing the missing .claude-pr parent case from #1311.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ci-cd
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100