claude-code - 💡(How to fix) Fix SDK worktree creation contaminates parent repo's core.hooksPath config

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

The Claude Agent SDK's worktree creation logic writes core.hooksPath to the parent repository's .git/config without using the --worktree flag, causing the parent repo to lose access to the user's global git hooks.

Root Cause

Because git worktrees share .git/config with the parent repo by default (unless extensions.worktreeConfig is enabled), this command writes into the parent's config, overriding any user-configured global hooks with a path to the parent's stock .git/hooks directory.

Code Example

let Y = WN(q, ".husky"),
    A = WN(q, ".git", "hooks"),
    O = null;
for (let j of [Y, A]) try {
  if ((await Y85(j)).isDirectory()) { O = j; break }
} catch {}
if (O) {
  await M7(D7(), ["config", "core.hooksPath", O], { cwd: K });
}

---

git -C <parent_repo> config extensions.worktreeConfig true

---

await M7(D7(), ["config", "--worktree", "core.hooksPath", O], { cwd: K });
RAW_BUFFERClick to expand / collapse

Summary

The Claude Agent SDK's worktree creation logic writes core.hooksPath to the parent repository's .git/config without using the --worktree flag, causing the parent repo to lose access to the user's global git hooks.

Mechanism

In @anthropic-ai/claude-agent-sdk (versions 0.40.1 and 0.42.1 observed), the copyWorktreeIncludeFiles function searches for .husky or .git/hooks directories and writes their path to the worktree's config:

let Y = WN(q, ".husky"),
    A = WN(q, ".git", "hooks"),
    O = null;
for (let j of [Y, A]) try {
  if ((await Y85(j)).isDirectory()) { O = j; break }
} catch {}
if (O) {
  await M7(D7(), ["config", "core.hooksPath", O], { cwd: K });
}

Because git worktrees share .git/config with the parent repo by default (unless extensions.worktreeConfig is enabled), this command writes into the parent's config, overriding any user-configured global hooks with a path to the parent's stock .git/hooks directory.

Impact

When Claude Code creates a worktree from a parent repository:

  • The parent repo's core.hooksPath is silently overwritten with /path/to/parent/.git/hooks
  • User's global git hooks are disabled in the parent repo
  • The path written typically contains only sample hook files, not functional hooks
  • User discovers the issue only when hooks stop firing

Evidence

  • SDK source locations: @anthropic-ai/claude-agent-sdk/cli.js function copyWorktreeIncludeFiles
  • Observed behavior: Five Claude Code worktrees spawned from gmail_extension repo (May 11-14) correlate with observed core.hooksPath override
  • Path written matches exactly: hooksPath = /Users/janac/Documents/GitHub/gmail_extension/.git/hooks
  • Verified git pull/fetch/merge do NOT restore the override (ruled out as alternative cause)

Suggested Fix

  1. Before creating worktrees, enable extensions.worktreeConfig=true on the parent repo:

    git -C <parent_repo> config extensions.worktreeConfig true
  2. Write core.hooksPath with the --worktree flag to isolate the config to the worktree only:

    await M7(D7(), ["config", "--worktree", "core.hooksPath", O], { cwd: K });

This ensures the hooks path applies only to the worktree and doesn't contaminate the parent repo's shared config.

Reproduction

  1. Configure global git hooks via git config --global core.hooksPath <path>
  2. Create a Claude Code worktree from any parent repo
  3. Check the parent repo's config: git -C <parent_repo> config core.hooksPath
  4. Observe the global hooks path has been replaced with <parent_repo>/.git/hooks

Environment

  • Claude Code versions with SDK 0.40.1 and 0.42.1
  • macOS (likely affects all platforms)
  • Git 2.x with standard worktree configuration

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING