Interactive Bash tool hangs after successful execution; tool_result is not written to session/UI
Summary
In Claude Code interactive mode, every Bash tool call gets stuck at Running... / reports an internal error and never returns output to the UI. The same Bash commands work in non-interactive mode (claude -p). Debug logs show that the local Bash command is actually executed successfully (tool_dispatch_end outcome=ok), but the corresponding tool_result is never written back to the session JSONL or rendered in the interactive UI.
This looks like an interactive-mode tool-result handling / streaming / session-state bug rather than a shell startup failure.
Environment
- Claude Code version:
2.1.119 - OS: macOS / Darwin
25.3.0 - Default shell:
/bin/zsh - Also reproduced after forcing Bash via Claude settings:
SHELL=/bin/bashCLAUDE_CODE_SHELL=/bin/bashCLAUDE_BASH_NO_LOGIN=1- Claude Code is configured through a local proxy at
http://127.0.0.1:5000. - Provider format that works for normal requests: OpenAI-compatible chat/completions.
What Works
Running Bash through non-interactive mode works and returns output, for example:
claude -p 'run pwd with Bash'
The command executes and returns normally.
What Fails
In interactive mode:
claude
Then ask Claude Code to run any Bash command, for example:
pwd
The UI shows the Bash tool as running, but it never surfaces the command output and the conversation does not continue normally. In some cases Claude Code reports an internal error.
This happens for all Bash commands tested, including trivial commands such as pwd, echo hi, and ls.
Debug Evidence
Using --debug-file, the debug log shows that the Bash tool is dispatched and completes successfully locally. The key observation is:
tool_dispatch_start ... tool_name=Bash ...
tool_dispatch_end ... outcome=ok ...
So shell process creation and command execution appear to succeed.
However, after this successful tool_dispatch_end outcome=ok, the expected tool result is not persisted into the session JSONL file. The session file does not contain the corresponding tool_result, and the interactive UI remains stuck at Running... without displaying the Bash output.
Things Already Tried
- Verified
claude -pnon-interactive mode works. - Reproduced in interactive mode with
claude. - Reproduced with
claude --bare. - Reproduced in a clean temporary directory.
- Disabled MCP servers for the test.
- Forced Claude Code to use
/bin/bashinstead of zsh. - Verified debug logs show
Using shell override: /bin/bash. - Reviewed shell startup files (
~/.zshrc,~/.zprofile, etc.). No obvious non-interactive shell pollution was found;~/.zshrchas an interactive guard like[[ $- != *i* ]] && return. - Disabled or adjusted several Claude Code environment flags related to prompt caching, telemetry/error reporting, experimental betas, background tasks, and fine-grained tool streaming. The issue persisted.
- Confirmed that switching the proxy to native Anthropic format is not viable in this environment because the upstream rejects some Claude Messages API fields such as
context_management; the OpenAI-compatible format is required for normal requests.
Expected Behavior
After the Bash subprocess completes successfully, Claude Code interactive mode should write a tool_result event to the session, render the Bash output in the UI, and continue the conversation.
Actual Behavior
The Bash subprocess appears to complete successfully according to debug logs, but the tool result is lost before it reaches the interactive UI/session state. The UI remains stuck at Running... or eventually reports an internal error.
Why I Think This Is a Claude Code Interactive-Mode Bug
The strongest signal is that tool_dispatch_end outcome=ok is present in the debug log, while the corresponding tool_result is missing from the session JSONL and the UI. This suggests the shell execution path itself is working, but the interactive-mode result propagation path is failing after successful tool execution.
This may be related to streaming/tool-result handling in interactive mode, especially when using an OpenAI-compatible proxy, but the failure point appears to be inside Claude Code after local Bash execution succeeds.
Related Issues
Possibly related:
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗