anthropics / anthropics/claude-code-action

`restoreConfigFromBase` crashes on dangling symlinks in `.claude/` directory

Open
#1,321 0 comments 3 reactions 0 assignees View on GitHub
bug p2
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.