[BUG] Setup hook with matcher "init" does not fire for \claude --init`, only for `--init-only``
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_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗