Inline shell mode (! commands) runs non-interactive zsh, breaking history, oh-my-zsh, and other interactive shell features
Summary
Claude Code's inline shell mode (\! <command>\) executes commands in a non-interactive zsh shell, which breaks a wide range of shell features that users rely on daily. This makes the inline shell mode feel unreliable compared to just opening a terminal.
Reproduction
! history
# omz_history:fc:13: no such event: 1
! hgrep somecommand
# omz_history:fc:13: no such event: 1
Any command that depends on shell history (including oh-my-zsh wrappers and aliases like hgrep) fails with this error.
What Breaks
Shell History
Running \! history\ or any history-dependent command fails:
omz_history:fc:13: no such event: 1
Root cause: Claude Code's shell snapshot deliberately sets HISTFILE="", SAVEHIST=0, and HISTSIZE=30 for isolation between commands. This has a critical side effect: oh-my-zsh only sets these variables when they are unset, so the snapshot's isolation values block oh-my-zsh from loading the user's actual history. The history builtin (wrapped by oh-my-zsh as omz_history) calls fc -l 1 internally — with no history loaded, event 1 doesn't exist and the command fails.
oh-my-zsh / zsh Interactive Features
hgrep(and similar history-search aliases that wrapfc) silently fail or error- Functions that check
[[ -o interactive ]]to conditionally set up state won't initialize - Some prompt-related functions and completions break
Environment Variables Blocked by Snapshot
HISTFILE,HISTSIZE,SAVEHIST— pre-set to isolation values ("",30,0), preventing oh-my-zsh from applying user defaults- Any exports in
.zshrcguarded by interactivity checks are skipped
Shell Snapshot Workaround Has Limits
Claude Code does create shell snapshots (e.g. ~/.claude/shell-snapshots/snapshot-zsh-*.sh) that capture functions and aliases from the user's environment. This works well — custom functions, aliases, etc. do load correctly. But it doesn't solve stateful or interactive-only features because each ! command still runs in a fresh, isolated, non-interactive shell with history stripped out.
Expected Behavior
Ideally, inline shell mode commands should run in an environment that matches the user's interactive shell as closely as possible — same HISTFILE, same shell options, same initialization path. At minimum:
- Load the user's actual history file so
history,fc, and history-search tools work - Respect
HISTFILE/HISTSIZE/SAVEHISTfrom the user's shell config rather than overriding them with isolation values - Optionally launch the shell as interactive (
zsh -i) so that oh-my-zsh and similar frameworks initialize fully — though this comes with tradeoffs (slower startup, prompt rendering side effects) that may warrant making it opt-in
Environment
- OS: macOS (Darwin 25.3.0)
- Shell: zsh with oh-my-zsh
- Claude Code: latest
- History file:
~/.zsh_history(3,000+ entries, works fine in normal terminals)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗