Stop and SubagentStop hooks can now return
additionalContextto keep the turn going without a hook error label. If you use stop hooks for guardrails, this replaces the block-and-error redirect pattern with a clean feedback loop.Hook
if: "Bash(...)"conditions were misfiring on every command with$()or$VAR, not just the targeted pattern. Fixed: the pattern now matches against commands inside subshells and backticks too. (more below)$TMPDIRregression from 2.1.154 is fixed. The override to/tmp/claude-{uid}was applying to all Bash commands instead of only sandboxed ones, breaking bazel and EDR-protected Go workflows. (more below)
New in 2.1.163
2.1.163 (June 5, 2026)
- Added
requiredMinimumVersionandrequiredMaximumVersionmanaged settings. Claude Code refuses to start if its version is outside the allowed range and directs the user to an approved version - Added
/plugin listcommand to list installed plugins, with--enabled/--disabledfilters - Added a "c to copy" shortcut to
/btwthat copies the raw markdown answer to the clipboard, preserving formatting when pasted elsewhere - Hooks: Stop and SubagentStop hooks can now return
hookSpecificOutput.additionalContextto give Claude feedback and keep the turn going without being labeled a hook error - Skills: added
\$escape syntax to include a literal$before a digit in command bodies - stdio MCP servers now receive the same
CLAUDE_CODE_SESSION_IDas hooks/Bash on--resume - Fixed
claude -phanging forever after its final result when a backgrounded command never exits. Background shells are now stopped ~5s after the result once stdin closes - Fixed
claude -pfailing with "ANTHROPIC_API_KEY required" on Bedrock/Vertex/Foundry whenCI=trueand no Anthropic API key is set - Fixed bash commands failing under bazel and EDR-protected Go workflows:
$TMPDIRwas overridden to/tmp/claude-{uid}for all commands instead of only sandboxed ones (regression in 2.1.154) - Fixed Bash commands failing on Windows with "EEXIST: file already exists" on the session-env directory when it has the read-only attribute or is inside OneDrive
- Fixed org-managed permission rules not applying for the entire session when the managed settings fetch completed during startup on a fresh config directory
- Fixed background sessions in
claude agentslosing their running background tasks when reattached after a Claude Code update - Fixed terminal misalignment and a multi-second hang when exiting the agent view by pressing Esc
- Fixed clicking Stop on a background-task chip in the desktop app not clearing the chip when the underlying process was already gone
- Fixed keyboard input becoming permanently unresponsive after a paste operation whose end marker is dropped by the terminal
- Fixed hook
if: "Bash(...)"conditions firing on every Bash command containing$()or$VAR; the pattern now matches against commands inside subshells and backticks too - Fixed deny rules on home-directory paths (e.g.
Read(~/Desktop/**)) not blocking Bash commands that reference the path via$HOME - Fixed a stray "(no content)" line left in the transcript after closing panel dialogs like /mcp and /plugins
- Background agent sessions now update to a new Claude Code version in the background, so opening a session after an update no longer waits on a cold restart
- Clearer descriptions for built-in commands and skills in the / menu
- The subscription-switch suggestion now shows in the startup announcement slot instead of a toast
claude agentsdispatching from the state-grouped view now starts the session in the directory the agent view was opened from
Notes
Hook if pattern matching scope
The if: "Bash(...)" condition was matching against the raw command string including shell variable expansions. A pattern like Bash(git push*) would fire on echo $(git status) or any command referencing $VAR, because the matcher tested the entire string, catching interpolated subshell expressions alongside the top-level command. The fix scopes the match correctly so patterns target only the commands you intended, including inside subshells and backticks.
If you noticed hooks firing unexpectedly on routine Bash commands since if conditions were introduced, this is the root cause.
$TMPDIR sandbox scoping
2.1.154 fixed $TMPDIR resolving to different paths in sandboxed vs unsandboxed commands, but the fix went too far. It overrode $TMPDIR to /tmp/claude-{uid} for every Bash command, not just sandboxed ones. Tools that rely on the real system $TMPDIR (bazel's action cache, Go test binaries under endpoint-detection-and-response scanners) broke because their temp directories moved without warning. 2.1.163 narrows the override back to sandboxed commands only.