Presence of ~/.bashrc (even empty) triggers full shell state capture with `set -o onecmd`, breaking npm/subprocess stdout on Windows/Git Bash
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?
On Windows with Git Bash, the mere presence of a ~/.bashrc file (even if completely empty) causes Claude Code to create bloated shell snapshots (~2254 bytes) that include set -o onecmd. This breaks all subprocess stdout, causing npm and other bash wrapper scripts to return no output.
When ~/.bashrc does NOT exist, Claude Code creates minimal snapshots (~282 bytes) that work correctly.
Root Cause: The onecmd shell option (equivalent to bash -t) causes bash to exit after executing one command, breaking subprocess stdout handling.
Minimal snapshot (282 bytes, works):
# Snapshot file
unalias -a 2>/dev/null || true
shopt -s expand_aliases
if ! command -v rg >/dev/null 2>&1; then
alias rg='...'
fi
export PATH=$PATH
Bloated snapshot (2254 bytes, broken):
# Snapshot file
unalias -a 2>/dev/null || true
# Functions
eval "$(echo '...' | base64 -d)" > /dev/null 2>&1
# Shell Options
shopt -u autocd
... (50+ shopt lines)
set -o braceexpand
set -o hashall
set -o interactive-comments
set -o monitor
set -o onecmd # <-- THIS BREAKS EVERYTHING
...
What Should Happen?
npm --versionand other bash wrapper scripts should return output correctly regardless of whether~/.bashrcexists- Shell snapshots should NOT include
set -o onecmdas this breaks subprocess stdout - Claude Code should either:
- NOT capture
set -o onecmdin shell snapshots - Explicitly disable it (
set +o onecmd) in all snapshots - Use the same minimal snapshot logic regardless of whether
.bashrcexists
Error Messages/Logs
Expected output (when ~/.bashrc does NOT exist):
$ npm --version
11.6.2
Actual output (when ~/.bashrc IS present):
$ npm --version
⎿ no content
(Tool ran without output or errors)
$ npm install
⎿ no content
(Tool ran without output or errors)
The command appears to succeed (no error code) but stdout is completely empty. This makes the bug extremely difficult to diagnose since there's no error message - just silent failure.
Steps to Reproduce
- On Windows with Git Bash, ensure
~/.bashrcdoes NOT exist - Delete existing shell snapshots:
rm -rf ~/.claude/shell-snapshots/* - Launch Claude Code and run
npm --version→ Works correctly, returns version (e.g., 11.6.2) - Check snapshot size:
ls -la ~/.claude/shell-snapshots/→ ~282 bytes - Create an empty .bashrc:
touch ~/.bashrc - Delete snapshots again:
rm -rf ~/.claude/shell-snapshots/* - Launch Claude Code and run any command to trigger new snapshot creation
- Run
npm --version→ Returns nothing (broken) - Check snapshot size:
ls -la ~/.claude/shell-snapshots/→ ~2254 bytes - Check snapshot contents:
cat ~/.claude/shell-snapshots/*.sh | grep onecmd→ Containsset -o onecmd
Reproducibility: Confirmed on TWO separate Windows machines with identical results. Both machines produce identical 2254-byte bloated snapshots containing set -o onecmd when an empty .bashrc exists.
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.12 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
Important: While the .bashrc file is a Git Bash configuration file, the bug affects npm in ALL terminals (PowerShell, CMD, Git Bash) because Claude Code's internal shell snapshot mechanism uses Git Bash regardless of the user's terminal.
Environment Details:
- Git for Windows: 2.52.0
- Node.js: 24.13.0
- npm: 11.6.2
- Tested terminals: PowerShell, CMD, Git Bash - all affected
Workaround: Remove ~/.bashrc and ~/.bash_profile. Move any needed environment variables to Windows System Environment Variables instead.
Key Evidence - Snapshot from second test machine:
# Line 75 of snapshot file:
set -o onecmd # <-- THE BUG
File size: 2254 bytes (vs 282 bytes when .bashrc doesn't exist)
Note: This bug affects ANY user who has a .bashrc file, even if it's empty. The file doesn't need to contain anything - its mere presence triggers Claude Code to capture full shell state including the problematic onecmd option.
18 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Subscribing - experiencing the same issue on Windows 11 with Git Bash. Workaround:
set +o onecmd; npm run build 2>&1Yep also happening to me too. Tried updated claude code and no luck.
Me 2, Windows 11.
Thanks Claude for founding this issue report ;)
Also experiencing the issue. Windows 11, Claude Code v2.1.20
simplest workaround for me is to open git bash and rename
~/.bashrcto~/.my_bashrc. works for me because i don't actually use Git Bash for regular work and if I need to use it I can manually source the file. Big PITA though.+1 on this. Running vitest via npm run test returns empty stdout and exit code 0 regardless of actual test results. Spent a good chunk of time debugging why CI was catching test failures that appeared to pass locally through Claude Code.
Environment: Windows 11, Node v24.12.0, Git Bash, Claude Code v2.1.23
Using PowerShell instead of Bash as a workaround for now.
Confirming this also affects macOS + native bash 3.2.57 (not just Windows/Git Bash).
Same root cause: shell snapshots at ~/.claude/shell-snapshots/ capture set -o onecmd even though it is not set in any user profile (.bashrc, .bash_profile, /etc/profile). Verified with set -o | grep onecmd showing onecmd off.
This has recurred 5 times across multiple Claude Code versions (Homebrew install). Each time the corrupted snapshot is deleted, the next session recreates it with the same bug.
Cross-platform reproduction confirms this is in the snapshot capture logic itself, not a platform-specific shell quirk.
Originally filed as #23841 (closing as duplicate of this).
Same issue on macOS. No fix so far, all my claude sessions can no longer invoke Bash tools.
All Bash commands suddenly started to exit with 127 mid session for me, and affects all my running claude sessions (about ~4 that I have open in various Terminal.app windows). Claude Code worked fine for months.
My
.bashrcand.profile(that I load from.bashrc) have not changed and do not include anyonecmdinstruction.set -o | grep onecmdshowsonecmd offin my shell, yet every snapshot capturesset -o onecmd. Removing/renaming.bashrcisn't practical for me on macOS.With the help of Claude I tried several workarounds but none helped. What I figured out was that this
set -o onecmdis added by Claude code into its shell snapshot file inside~/.claude/shell-snapshots/_the first time_ it runs theBashtool. Which I think the OP steps also indicate.✅ It works when I revert back to Claude
2.1.50.❌ Failing:
2.1.51and2.1.52(current latest).Error: Exit code 127.---
Minimal steps to test different versions:
npm install -g @anthropic-ai/claude-code@<VERSION>clauderun bash 'echo hi'As one liner:
The
exit code 127problem is still happening on Claude code2.1.68for me.I eventually fixed this by getting rid of my
~/.bashrcon my Mac. Working fine on stable claude2.1.58now.My shell setup using
bashwas maybe a bit awkward:~/.profilewith all my shell customizations (PATH, PS1, aliases, shell completions)~/.bashrcwas sourcing the~/.profileI changed it to have all my customizations in
~/.bash_profileinstead and remove both~/.profileand~/.bashrc. This seems to be a better approach on Mac and using Terminal.app anyway.Workaround:
BASH_ENVwith DEBUG trapFound a reliable workaround for the
set -o onecmdsnapshot issue on macOS.The root cause: shell snapshots capture
set -o onecmdfrom non-interactive bash defaults. When the snapshot is later sourced,onecmdcauses bash to exit after one command, breaking Claude Code's multi-command wrapper. This manifests as intermittent "(No output)" from the Bash tool.Fix
Create
~/.claude-bash-env.sh:Add to
~/.claude/settings.json:Why it works
BASH_ENVis sourced by non-interactive bash before executing any commands — including when Claude Code sources the snapshot. The DEBUG trap fires after each command, so even when the snapshot re-enablesonecmdviaset -o onecmd, the trap immediately disables it again before the next command runs.Things that did NOT work
set +o onecmdin~/.bashrcor~/.bash_profile— bash re-enablesonecmdafter sourcing config filesshellSnapshotEnabled: falsein settings.json — ignoredSHELLOPTSenv var — read-only, cannot disable optionsLinux confirmation + process accumulation (fork-bomb behaviour)
Confirming this also affects Fedora 43 (Linux 6.19.7) with Bash 5.x, Claude Code 2.1.77.
Additional finding:
set -o monitorcompounds the problemThe snapshot captures two problematic options:
set -o monitoris enabled by default in interactive bash on Linux. When restored in the non-interactivebash -csubshell, it causes the process to sleep indefinitely waiting for terminal control signals that never come.Process accumulation → system instability
The combination creates a runaway process accumulation:
set -o onecmd+set -o monitorbash -c "source snapshot.sh && ... && eval 'COMMAND' && pwd -P >| /tmp/claude-*-cwd"hangs — the process never writes to the cwd fileAll processes in
S(sleeping) state — stuck on job control signals, never completing.Suggested fix
The snapshot generation should exclude at minimum these options:
Or better, explicitly disable them after sourcing:
Workaround
Environment
set -o monitoris ON by default in interactive bash on all major Linux distrosAdditional symptoms and workaround for set -o truncation
I experienced a related but slightly different symptom on the same setup (Windows + Git Bash via Scoop).
Environment:
OS: Windows 11
Claude Code: v2.1.45
Git Bash installed via Scoop (~/.scoop/apps/git/current/bin/bash.exe)
Symptom:
The shell snapshot was truncating set -o <option> entries — stripping the set -o prefix and leaving just the option name as a bare command. For example:
set -o monitor → became or in the snapshot (line 3)
set -o checkhash → became heckhash in the snapshot (line 5)
This caused every bash command in Claude Code to fail with command not found errors for or, heckhash, and dozens of base64-encoded lines from git internals, making Claude Code completely unusable — even basic pwd and git status failed.
Root cause:
Same as #19057 — presence of ~/.bashrc triggers full shell state capture, which then gets corrupted when written to the snapshot file.
Workaround (better than removing .bashrc):
Instead of removing .bashrc, add these two lines at the top of ~/.bashrc to turn off the problematic shell options before Claude Code captures the snapshot:
bashset +o monitor
set +o checkhash
This prevents those options from appearing in the snapshot while keeping .bashrc intact for env vars and PATH configuration — which are required for tools like curl, jq, and custom CLI scripts to work inside Claude Code on Windows.
Note: Make sure .bashrc is saved with Unix line endings (LF not CRLF), otherwise bash will fail to source it correctly. In PowerShell:
powershell$content = Get-Content C:\Users\<you>\.bashrc -Raw
$content = $content -replace "
rn", "`n"[System.IO.File]::WriteAllText("C:\Users\<you>\.bashrc", $content)
Subscribing. Issue is still there (2.1.107, VS Code, Windows 11)
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.