[BUG] Setup hook with matcher "init" does not fire for \claude --init`, only for `--init-only``

Resolved 💬 3 comments Opened Jan 30, 2026 by UeshibaKyohei Closed Feb 28, 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?

The Setup hook with matcher: "init" does not fire when running claude --init, but it does fire correctly when running claude --init-only.
Additionally, the --init flag is not listed in claude -h, even though the CLI accepts it and runs without an error.

I confirmed this by configuring a minimal Setup hook that appends a JSON line to ./claude-setup-hook.jsonl whenever Setup:init runs. With claude --init-only the file is created and appended as expected, but with claude --init the file is not created (or remains empty), which indicates the hook is not executed.

What Should Happen?

Based on the hooks documentation and how --init-only behaves, my understanding is:

claude --init should:

Trigger the Setup hook with matcher: "init" (i.e. Setup:init).

Then continue into a normal interactive session (e.g. SessionStart).

claude --init-only should:

Trigger the same Setup:init hook.

Then exit immediately without starting an interactive session.

In other words, both --init and --init-only should fire the same Setup:init hooks; the only difference should be whether an interactive session starts afterwards.

So when I run claude --init, I would expect the Setup:init hook to run and append a log line to ./claude-setup-hook.jsonl, just like it does for claude --init-only.

Error Messages/Logs

Steps to Reproduce

Environment

Have a project with .claude/settings.json at the project root.

Claude Code is installed and claude is available on the PATH.

(Optional but recommended) Confirm version:

bash
claude --version
Minimal .claude/settings.json

Create the following file (or reduce your existing config to this minimal example):

text
{
"hooks": {
"Setup": [
{
"matcher": "init",
"hooks": [
{
"type": "command",
"command": "echo '{\"triggered_at\": \"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'\", \"event\": \"Setup:init\"}' >> ./claude-setup-hook.jsonl",
"timeout": 10
}
]
}
]
}
}
Clean up any previous log

bash
rm -f ./claude-setup-hook.jsonl
Run with --init-only (this works)

bash
claude --init-only
cat ./claude-setup-hook.jsonl
Expected / actual result:

claude-setup-hook.jsonl is created.

It contains one JSON line like:

json
{"triggered_at": "...", "event": "Setup:init"}
This confirms that Setup:init does fire for --init-only.

Clean up again

bash
rm -f ./claude-setup-hook.jsonl
Run with --init (this is where the issue occurs)

bash
claude --init
cat ./claude-setup-hook.jsonl
Actual result:

claude-setup-hook.jsonl is not created, or remains empty.

There is no evidence that the Setup:init hook was executed.

(Optional) Confirm that the flag exists but is undocumented

bash
claude -h # or: claude --help
The flags --init, --init-only, and --maintenance do not appear in the help output.

Despite this, claude --init-only and claude --init both run, and only --init-only triggers the Setup:init hook.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.25

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

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