Bug: Intermittent ZodError in Tool Permission Validation (updatedInput undefined)
Bug: Intermittent ZodError in Tool Permission Validation
Summary
Claude Code intermittently fails with a ZodError when validating tool permission requests. The error occurs before tools execute, blocking Write, Bash, MCP tools, WebFetch, WebSearch, and AskUserQuestion operations. Read-only tools (Read, Glob, Grep, TodoWrite, Task) are unaffected.
Error Message
Tool permission request failed: ZodError: [
{
"code": "invalid_union",
"errors": [
[
{
"expected": "record",
"path": ["updatedInput"],
"message": "Invalid input: expected record, received undefined"
}
],
[
{
"code": "invalid_value",
"values": ["deny"],
"path": ["behavior"],
"message": "Invalid input: expected \"deny\""
},
{
"expected": "string",
"path": ["message"],
"message": "Invalid input: expected string, received undefined"
}
]
]
}
]
Affected Tools
| Tool | Affected | Notes |
|------|----------|-------|
| Write | ✅ Yes | File creation/modification blocked |
| Bash | ✅ Yes | Command execution blocked |
| Edit | ✅ Yes | File editing blocked |
| WebFetch | ✅ Yes | URL fetching blocked |
| WebSearch | ✅ Yes | Web searches blocked |
| AskUserQuestion | ✅ Yes | User prompts blocked |
| MCP tools (mcp__*) | ✅ Yes | All MCP tool calls blocked |
| Read | ❌ No | Works normally |
| Glob | ❌ No | Works normally |
| Grep | ❌ No | Works normally |
| TodoWrite | ❌ No | Works normally |
| Task | ❌ No | Works normally |
Environment
- Claude Code Version: 2.1.19
- Platform: macOS Darwin 25.2.0 (Apple Silicon)
- Node.js: v22.x
- Installation: npm global install
Steps to Reproduce
- Start a Claude Code session in any project directory
- Attempt to use Write, Bash, or MCP tools
- The error occurs intermittently - not every time, but frequently enough to block work
- Retry the same operation - it may succeed or fail again
Specific reproduction for MCP tools:
- Configure a hosted MCP server (e.g.,
mcp.serendb.com/mcp) - Attempt to call any MCP tool (e.g.,
mcp__seren__list_projects) - Permission validation fails with ZodError before the tool executes
Expected Behavior
Tool permission validation should succeed and either:
- Allow the tool to execute (with
updatedInputcontaining the approved input) - Deny the tool with a clear message
Actual Behavior
The Zod schema validation fails because neither valid union branch is satisfied:
updatedInputisundefinedinstead of a recordbehavioris not"deny"andmessageisundefined
This suggests the permission response object is malformed or incomplete before validation.
Root Cause Analysis
From inspecting Claude Code's source (cli.js), the permission system expects:
// Option 1: Approved
{ behavior: "allow", updatedInput: { /* tool input */ } }
// Option 2: Denied
{ behavior: "deny", message: "Reason for denial" }
// Option 3: MCP tools return
{ behavior: "passthrough", message: "MCPTool requires permission." }
The ZodError indicates the permission response doesn't match any valid schema branch. Possible causes:
- Race condition in concurrent tool permission handling
- State corruption when multiple permission requests are in flight
- Timeout/incomplete response from internal permission resolution
- Schema mismatch for certain tool types or edge cases
Workarounds Attempted
- Retry - Sometimes succeeds on second attempt (intermittent nature)
- Disable plugins - Issue persists with all plugins disabled
- Fresh session - Issue can occur in new sessions
- Different tools - Read-only tools work; write tools fail
Additional Context
- Plugins installed: claude-mem, context7, code-review, frontend-design, rust-analyzer-lsp, elevator-notifications
- Hooks active: UserPromptSubmit, PostToolUse (from claude-mem) - but these don't intercept permission validation
- MCP servers: Seren MCP (
mcp.serendb.com), context7 - Comparison: The same MCP server works correctly in Cursor's Claude integration (different permission architecture)
Impact
This bug significantly impacts productivity:
- Cannot write files when the error occurs
- Cannot run bash commands
- Cannot use MCP tools
- Must retry operations multiple times
- No clear pattern to avoid triggering the bug
Suggested Investigation Areas
- Check permission validation flow for race conditions
- Verify all code paths populate
updatedInputor setbehavior: "deny"withmessage - Add defensive checks before Zod validation to catch undefined values
- Review MCP tool permission handling (
behavior: "passthrough"path) - Check for async timing issues in permission resolution
Related
- This may be related to MCP tool permission handling specifically
- The
behavior: "passthrough"return from MCP tools may not be properly handled in all code paths
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗