[BUG] Agent hook 'prompt' fields silently stripped from settings.json Stop hooks
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?
Agent hooks in the Stop event repeatedly lose their prompt fields. The prompt field is silently stripped, leaving the hook definition with only type, timeout, and statusMessage — but no prompt. Claude Code then rejects the entire settings.json on next startup:
Settings Error
/Users/matthewherod/.claude/settings.json
└ hooks
└ Stop
└ 0
└ hooks
├ 0
│ └ prompt: Expected string, but received undefined
├ 1
│ └ prompt: Expected string, but received undefined
└ 3
└ prompt: Expected string, but received undefined
Files with errors are skipped entirely, not just the invalid settings.
This has occurred repeatedly across multiple sessions. Each time, the prompts must be manually restored from a gist backup. The hooks are valid JSON and pass schema validation immediately after restoration.
Configuration (working state before stripping)
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "agent",
"timeout": 60,
"statusMessage": "Auditing completion...",
"prompt": "You are a strict completion auditor. Review the conversation context in $ARGUMENTS.\n\nIf stop_hook_active is true, respond {\"ok\": true} immediately — do not loop.\n\nBlock stopping if:\n1. User's most recent explicit request has NOT been fully completed\n..."
},
{
"type": "agent",
"timeout": 60,
"statusMessage": "Auto-committing changes...",
"prompt": "You are an auto-commit agent. Before the session stops, check if there are uncommitted changes in a git repo and commit them.\n..."
},
{
"type": "command",
"command": "afplay /System/Library/Sounds/Hero.aiff &"
},
{
"type": "agent",
"timeout": 60,
"statusMessage": "Updating memory...",
"prompt": "You are a memory updater. Review the session context provided in $ARGUMENTS, including the transcript at the transcript_path.\n..."
}
]
}
]
}
}
After stripping, the same hooks appear as:
{
"type": "agent",
"timeout": 60,
"statusMessage": "Auditing completion..."
}
The prompt field is simply gone. No error is logged when it disappears — only on next startup when validation catches the missing field.
What Should Happen?
Agent hook prompt fields should persist across sessions. They should never be silently removed from settings.json.
Suspected Causes
- Claude Code writing settings.json — When the application updates permissions, model, or other settings, it may serialize the config without preserving all hook fields (particularly long
promptstrings of 700-1000+ characters) - The Edit tool — When the model edits settings.json, long prompt strings may be dropped during old_string/new_string replacement because they exceed what the model tracks accurately
- Schema migration — A settings format migration may strip fields it doesn't recognize or doesn't expect
Steps to Reproduce
- Configure 3 agent hooks in
Stopevent, each with apromptfield (700-1100 characters) - Use Claude Code across multiple sessions
- Observe that
promptfields disappear from the agent hooks - On next startup, receive the "Expected string, but received undefined" validation error
Workaround
Keep a backup of the hooks configuration (e.g., in a GitHub gist) and restore prompt fields manually when they disappear. A PostToolUse hook can auto-sync the hooks section to a gist for easy recovery.
Claude Model
Sonnet (default)
Is this a regression?
Unknown — agent hooks with prompt are a relatively new feature
Claude Code Version
2.1.30+
Platform
Anthropic API (macOS)
Operating System
macOS (Darwin 25.2.0)
Terminal/Shell
Terminal.app / iTerm2
Additional Information
- Prompt lengths when working: 1069, 1067, and 718 characters respectively
- The
commandtype hook (Hero.aiff sound) in the same Stop event is never affected — onlyagenttype hooks lose theirprompt - Validated with Zod schema — prompts pass validation immediately after manual restoration
- This has happened 5+ times across sessions on the same day
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗