[BUG] Bash Renders full Private Key for deleted file
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?
Renaming a secret file via Bash mv rendered its full contents (private key) as a "Deleted file… │
│ │ - What happened: Claude ran mv project<deleted_for_security> inside the repo. The Claude Code UI displayed a "Deleted project-<id>.js… with full private key.
What Should Happen?
The files full contents (private key) should not be passed to the context window when renaming a file.
Error Messages/Logs
Steps to Reproduce
Steps to Reproduce
- Open Claude Code (CLI) in any git repository on Windows 11 with the Bash tool
available. Permission mode: bypass permissions (default tool display, not
verbose).
- Create a JSON file inside the repo that looks like a Google service-account
key. Put it in a path that is gitignored (so it is never committed):
mkdir -p apps/demo
echo "apps/demo/secret.json" >> .gitignore
cat > apps/demo/downloaded-key.json <<'EOF'
{
"type": "service_account",
"project_id": "demo-project",
"private_key_id": "0123456789abcdef",
"private_key": "-----BEGIN PRIVATE KEY-----\nFAKEKEYFAKEKEYFAKEKEY\n-----END PRIVATE KEY-----\n",
"client_email": "demo@demo-project.iam.gserviceaccount.com"
}
EOF
- Ask Claude: "Rename apps/demo/downloaded-key.json to apps/demo/secret.json
and confirm git ignores it. Do not print the private key."
- Claude runs a Bash command equivalent to:
mv apps/demo/downloaded-key.json apps/demo/secret.json && git check-ignore -v apps/demo/secret.json
Claude's own stdout contains only the gitignore match line. It does not
print the file contents.
- Observe the tool-result block rendered in the terminal UI under
"Ran N shell commands".
Expected:
The rename is reported (or a path-only summary such as
"Deleted apps/demo/downloaded-key.json") with no file body shown, because
the command did not output the file and the file is gitignored.
Actual:
The UI appends a file-change diff:
Deleted apps/demo/downloaded-key.json (+0 -13)
{
"type": "service_account",
"project_id": "demo-project",
"private_key_id": "0123456789abcdef",
"private_key": "-----BEGIN PRIVATE KEY-----\nFAKEKEY...
The full contents of the removed file, including the private_key value, are
printed into the conversation and persisted in the session transcript
(~/.claude/projects/<project>/<session-id>.jsonl).
Notes:
- Happens on mv (seen in the wild with a real Google Play service-account key,
which then had to be rotated). The diff comes from the file-change watcher,
not from command stdout, so redacting output does not help.
- The file was gitignored; gitignore status is not consulted before rendering.
- Suggested fix: do not render bodies of deleted/moved files in the change
summary, skip gitignored paths, and/or redact lines matching obvious secret
patterns (BEGIN PRIVATE KEY, "private_key", AWS/API key shapes).
Environment:
Claude Code CLI on Windows 11 Pro 10.0.26300, Git Bash shell, model
claude-fable-5-1. Observed 2026-10-01 ~01:06 EDT.
Claude Model
Other
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
10.0.26300
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
_No response_