[BUG] `--worktree` fails in non-git repos even when `WorktreeCreate` hook is configured

Resolved 💬 4 comments Opened Mar 10, 2026 by miaekim Closed Apr 18, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

claude --worktree <name> immediately exits with an error in non-git repositories (e.g., Mercurial/Sapling), even when a WorktreeCreate hook is configured in ~/.claude/settings.json. The git repository check in the setup function runs before the hook is considered, so the hook never fires.

What Should Happen?

When a WorktreeCreate hook is registered, claude --worktree should delegate to that hook instead of requiring a git repository. The hook mechanism exists precisely to support non-git VCS systems (Mercurial, Sapling, SVN, etc.), and the internal worktree creation function already handles this correctly — it just never gets called.

Error Messages/Logs

Error: Can only use --worktree in a git repository, but /path/to/repo is not a git repository

Steps to Reproduce

  1. Navigate to a non-git repository (e.g., a Mercurial/Sapling repo)
  2. Add a WorktreeCreate hook to ~/.claude/settings.json:

``json
{
"hooks": {
"WorktreeCreate": [
{
"type": "command",
"command": "my-worktree-create-script $name"
}
]
}
}
``

  1. Run claude --worktree mytree
  2. Error fires immediately — the hook is never invoked

Claude Model

Opus

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

v2.1.58

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Root cause in code:

The setup function checks isGitRepo() before the worktree creation function is called. The worktree creation function itself already correctly checks for a WorktreeCreate hook first, but the early guard prevents it from ever being reached:

setup() {
  if (worktreeFlag) {
    if (!isGitRepo())          // ← blocks non-git repos before hooks are checked
      exit("not a git repo")
    // ... git-specific setup ...
    createWorktree()           // ← never reached for non-git repos
  }
}

createWorktree() {
  if (hasWorktreeCreateHook()) {  // ← correctly checks for hook first
    delegateToHook(name)          //    but never gets called
  } else {
    // git-based worktree
  }
}

Suggested fix: Check for a WorktreeCreate hook before the git repo check. If a hook exists, skip git-specific pre-checks and delegate directly:

if (worktreeFlag) {
  if (hasWorktreeCreateHook()) {
    // Hook-based path: skip git checks entirely
    let result = await createWorktree(sessionId, name);
    process.chdir(result.worktreePath);
  } else {
    // Existing git-based path (unchanged)
    if (!isGitRepo()) exit("not a git repo");
    // ...
  }
}

This is consistent with how agent worktree creation and the worktree creation function itself already handle the hook-based path.

Related: #27439 — --worktree also fails in bare git repos due to the same early guard. Both issues stem from the overly restrictive git check in the setup function.

Environment:

  • OS: macOS / Linux
  • VCS: Sapling (Mercurial-based)

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗