claude-code - 💡(How to fix) Fix [BUG] PreToolUse updatedInput silently ignored for Edit tool — works for Read and Bash [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#47853Fetched 2026-04-15 06:40:28
View on GitHub
Comments
0
Participants
1
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
labeled ×6cross-referenced ×1

Root Cause

PreToolUse hooks that return permissionDecision: "allow" with updatedInput have the updatedInput completely ignored for the Edit tool. The original tool input is executed instead of the modified input. The Edit tool then fails because the original old_string doesn't match the file.

Fix Action

Fix / Workaround

Current workaround: use permissionDecision: "deny" with the corrected old_string in the reason, forcing Claude to retry manually. This adds a round-trip per correction.

Code Example

"PreToolUse": [
  {
    "hooks": [
      {
        "type": "command",
        "command": "node my-hook.js",
        "timeout": 10
      }
    ]
  }
]

---

process.stdout.write(JSON.stringify({
  hookSpecificOutput: {
    hookEventName: 'PreToolUse',
    permissionDecision: 'allow',
    updatedInput: {
      file_path: '/path/to/file.js',
      old_string: 'corrected old string that exists in file',
      new_string: 'new content',
      replace_all: false
    }
  }
}));
RAW_BUFFERClick to expand / collapse

Preflight Checklist

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

What's Wrong?

PreToolUse hooks that return permissionDecision: "allow" with updatedInput have the updatedInput completely ignored for the Edit tool. The original tool input is executed instead of the modified input. The Edit tool then fails because the original old_string doesn't match the file.

updatedInput works correctly for:

  • ReadupdatedInput with modified offset/limit is applied (confirmed in existing setup)
  • BashupdatedInput with modified command is applied (confirmed in existing setup)

The hooks documentation lists Edit as a supported tool for updatedInput.

What Should Happen?

When a PreToolUse hook returns permissionDecision: "allow" with updatedInput containing {file_path, old_string, new_string, replace_all}, the Edit tool should execute with the updated old_string.

Reproduction

Single hook setup (settings.json — only ONE PreToolUse entry, no plugin hooks):

"PreToolUse": [
  {
    "hooks": [
      {
        "type": "command",
        "command": "node my-hook.js",
        "timeout": 10
      }
    ]
  }
]

Hook script outputs valid JSON with corrected old_string:

process.stdout.write(JSON.stringify({
  hookSpecificOutput: {
    hookEventName: 'PreToolUse',
    permissionDecision: 'allow',
    updatedInput: {
      file_path: '/path/to/file.js',
      old_string: 'corrected old string that exists in file',
      new_string: 'new content',
      replace_all: false
    }
  }
}));

Verified manually: piping the same stdin to the hook script produces the correct JSON output with all 4 Edit parameters. The corrected old_string IS present in the file on disk.

Result: Edit tool receives the original uncorrected old_string and fails with "String to replace not found in file."

Tested Scenarios

VariationResult
permissionDecision: "allow" + updatedInput❌ Ignored for Edit
permissionDecision: "ask" + updatedInput❌ Ignored for Edit
updatedInput with additionalContext❌ Ignored
updatedInput without additionalContext❌ Ignored
Single hook in settings.json (no plugin hooks)❌ Ignored
Single hook in plugin hooks.json (no settings hooks)❌ Ignored
Hook routed via settings.json spawnSync to Python script❌ Ignored
permissionDecision: "deny" with permissionDecisionReason✅ Works (Edit blocked, reason shown)
updatedInput for Read tool (offset/limit)✅ Works (input modified)
updatedInput for Bash tool (command)✅ Works (command rewritten)

All 4 Edit parameters are provided in updatedInput: file_path, old_string, new_string, replace_all.

Use Case

I have a PreToolUse hook that detects when a linter/formatter modified a file after Claude's last read (e.g., indentation changed from 4-space to 2-space). The hook corrects Claude's stale old_string to match the current file content and returns it via updatedInput.

Current workaround: use permissionDecision: "deny" with the corrected old_string in the reason, forcing Claude to retry manually. This adds a round-trip per correction.

Related

  • #15897 — updatedInput ignored when multiple PreToolUse hooks execute (different root cause — our bug reproduces with a single hook)

Environment

  • Claude Code version: Latest (VS Code extension)
  • Platform: Windows 11
  • Hook source: Both settings.json and plugin hooks.json tested independently

extent analysis

TL;DR

The issue can be resolved by investigating and fixing the specific handling of updatedInput for the Edit tool in the Claude Code extension, potentially involving modifications to how the extension processes PreToolUse hooks.

Guidance

  • Review the Claude Code extension's source code to identify why updatedInput is ignored for the Edit tool, despite being supported according to the documentation.
  • Verify that the updatedInput object is correctly formatted and contains all required properties (file_path, old_string, new_string, replace_all) when returned by the PreToolUse hook.
  • Compare the handling of updatedInput for the Edit tool with the handling for the Read and Bash tools, where updatedInput is applied correctly, to identify potential differences or bugs.
  • Consider temporarily modifying the hook to log or output detailed information about the updatedInput object and the Edit tool's execution to gain more insight into the issue.

Example

No specific code example can be provided without access to the Claude Code extension's source code. However, ensuring the updatedInput object is correctly constructed, as shown in the issue, is crucial:

process.stdout.write(JSON.stringify({
  hookSpecificOutput: {
    hookEventName: 'PreToolUse',
    permissionDecision: 'allow',
    updatedInput: {
      file_path: '/path/to/file.js',
      old_string: 'corrected old string that exists in file',
      new_string: 'new content',
      replace_all: false
    }
  }
}));

Notes

The issue seems specific to the Edit tool and the handling of updatedInput within the Claude Code extension. The fact that updatedInput works for other tools (Read, Bash) suggests a tool-specific issue rather than a general problem with PreToolUse hooks or the updatedInput mechanism.

Recommendation

Apply a workaround by modifying the PreToolUse hook to handle the correction internally if possible, or wait for an update to the Claude Code extension that addresses the issue with updatedInput for the Edit tool. The current workaround using permissionDecision: "deny" with the corrected old_string in the reason is less ideal due to the added round-trip.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] PreToolUse updatedInput silently ignored for Edit tool — works for Read and Bash [1 participants]