claudekit / updates / claude-code-2-1-251
[ PATCH · ]

Claude Code 2.1.251

New `PreModelSwitch` and `PostModelSwitch` hook events let you block, confirm, or annotate a model switch, and `SessionStart` resume hooks now receive session staleness and the estimated re-cache cost. Remote Control clients get live streaming of a foreground subagent's tool calls and results, `/cost` gains a per-session prompt-cache line (hit ratio, misses, tokens re-cached, warm/cold) with a matching `prompt_cache` object for status line scripts, and `/usage` gains a Spend limit bar. A run of permission fixes closes paths around the permission check: file tools following a symlink swapped after the check, plugin commands pointing outside the plugin directory, and Grep and Glob skipping `Read(...)` deny rules through a symlinked search path. Project `.claude/settings.json` `env` can no longer set `CLAUDE_CONFIG_DIR` or `TMPDIR`, and `CLAUDE_CODE_SUBAGENT_MODEL` now sets the default subagent model rather than overriding everything.

Official announcement →

This article is a summary based on official documentation.

What changed

Claude Code 2.1.251 shipped on August 28, 2026. The center of this release is the permission boundary: file tools, plugin commands, Grep and Glob, and the Workflow tool no longer offer ways to reach a path the permission check never approved. On top of that come hooks around model switching, new visibility into prompt-cache behavior and spend limits, and live subagent output on Remote Control — plus a narrowed scope for project settings and for CLAUDE_CODE_SUBAGENT_MODEL.

New features

  • PreModelSwitch and PostModelSwitch hook events

    A model switch mid-session was not something a hook could see, let alone stop. The two new events let you block, confirm, or annotate a model switch. SessionStart resume hooks also now receive session staleness and the estimated re-cache cost.

  • Live subagent streaming to Remote Control

    Remote Control clients could only see a subagent’s status, not what it was doing. A foreground subagent’s tool calls and results now stream live to connected clients. Background subagents, the default, still show status only.

  • Spend limit bar in /usage

    For developers behind a Claude apps gateway with spend limits, there was no way to see the remaining spend from inside the session. /usage now shows a Spend limit bar, and status line scripts can read the same value from the rate_limits.spend_limit field.

  • Per-session prompt-cache line in /cost

    Nothing in the session told you whether cost was climbing because the prompt cache kept missing. /cost now reports hit ratio, misses, tokens re-cached, and warm/cold per session, with a matching prompt_cache object for status line scripts.

  • Background session commands in claude --help

    attach, logs, stop, respawn, and rm were undiscoverable from the help output. They are now listed in claude --help, and the --resume message for a running background session names the exact claude attach <id> command.

Key improvements

  • Approval required for sensitive server-managed settings

    Server-managed settings that terminate sandbox TLS, route sandbox traffic through your own proxy, inject credentials, or weaken sandbox isolation applied as delivered. They now require approval before they apply. ANTHROPIC_CUSTOM_HEADERS from managed or project settings likewise requires approval when it sets a credential, org/tenant, routing, or API-behavior header (e.g. Authorization, Host).

  • Narrower env scope for project settings

    Project-level .claude/settings.json env could relocate the config and temp directories. It no longer sets CLAUDE_CONFIG_DIR, CLAUDE_CODE_TMPDIR, or TMPDIR/TMP/TEMP; set them in your shell, user, or managed settings instead.

  • CLAUDE_CODE_SUBAGENT_MODEL sets a default, not an override

    The variable overrode every subagent model, so an agent definition’s model: and an explicit per-spawn model were ignored. It now sets the default subagent model, and both of those take precedence over it.

  • /effort is saved per model

    Changing your effort level carried across model switches, so keeping different levels per model was not possible. /effort now saves your default effort level per model.

  • The managed settings approval dialog lists only what changed

    The dialog showed the full settings payload, making a new entry hard to spot. It now lists only the settings that changed since you last approved them.

  • Claude in Chrome browser actions go through Claude Code permission checks

    Some browser actions were handled by the Chrome extension’s own prompts, including in sessions with telemetry disabled. They now always go through Claude Code’s permission checks.

  • Malformed tool calls are dropped from the retry context

    When the model’s tool call came back malformed, the broken output stayed in context on retry. It is now dropped from the retry context, including on Bedrock, Vertex, and Foundry.

  • Lower CPU usage and a smaller install

    Interactive sessions re-rendered the UI redundantly during turns; cutting those re-renders lowers CPU usage. The native binary is about 5 MB smaller, and dropping syntax highlighting for six rarely used languages (1c, gml, isbl, mathematica, maxima, sqf) takes off another 2.5 MB.

  • Clearer proxy failures in cloud sessions

    When the session’s network proxy dropped a connection during a Bash command, the tool result said only “connection reset”. It now names the host and reason.

  • Install suggestions wait for your prompt

    Plugin and LSP install suggestions and the auto-mode default offer could appear while you were typing, so the Enter that sends your prompt answered them instead. They now wait until you’ve sent or cleared what you’re typing.

  • Better framing of messages from your own subagents

    A message from a subagent in your session read like it came from elsewhere. Claude is now told the sender is a worker inside this session, not an unrelated Claude session. The prompt placeholder also reads “Message @name…” while viewing a background subagent or fork transcript opened from the subagent panel or /tasks.

Bug fixes

Security & permissions

  • File tools (Read, Write, Edit) following a symlink swapped inside the working directory after the permission check — fixed; this could read or write outside the approved location.
  • Plugin commands declared in a marketplace entry being able to point outside the plugin directory — fixed; such paths are now rejected with a path-traversal error.
  • Grep and Glob not applying Read(...) deny rules to files reached through a symlinked search path — fixed.
  • Project settings being able to enable detailed beta tracing or raw API body logging — fixed, along with a lower-scope beta tracing endpoint bypassing an OTLP collector pinned by managed settings or a host app.
  • The Workflow tool reading (and quoting in errors) a scriptPath outside what the session may read before the permission check ran — fixed.
  • Bash permission checks auto-approving commands that assign an arithmetic expression to an integer shell variable (e.g. OPTIND=1/0, RANDOM=2+2) — fixed; these now prompt for approval.

Sessions & models

  • Conversations getting stuck on “text content blocks must be non-empty” errors after a turn where the model produced only thinking — fixed.
  • Opus 5 requests failing with “effort … is not supported when thinking is disabled” when effort was xhigh/max and thinking was turned off — effort is now sent as high in that case.
  • The first launch on a fresh install starting in default mode instead of auto mode for accounts whose startup default is auto mode — fixed.
  • Managed-settings disableAutoMode arriving mid-session not moving an already-running auto-mode session back to default mode — fixed.
  • Session transcripts being silently overwritten when a directory change relocated a session onto an existing same-ID transcript — fixed.
  • A “switch to Opus 1M for 5x more context” tip appearing even when the current Opus model already has a 1M context window — fixed.
  • --input-format stream-json merging client-injected assistant tool calls sent without a message id into the first one and losing their results — fixed, including when resuming older sessions.

Agents & background sessions

  • TUI lag with many parallel subagents — per-second progress ticks now replace their predecessor instead of piling up in the transcript.
  • A teammate’s final answer not reaching the team lead in agent teams — it now arrives in the idle notification instead of a content-free “available” notice.
  • Background subagents being unable to reply to a message from an unnamed sibling or parent agent — fixed; from was the agent type, which is not an address.
  • Background sessions and their subagents being unable to edit files inside a git worktree they created with git worktree add — fixed.
  • Background sessions occasionally starting without any plugin skills, and staying that way, when another Claude Code process was refreshing the plugin marketplace at the same moment — fixed.
  • Selecting text in an opened background session inside tmux over SSH falling back to OSC 52 — it now copies to the tmux buffer like a foreground session.

Remote & cloud sessions

  • Replying to a message Claude Desktop delivered from another session — SendMessage to that session id now delivers through Claude Desktop instead of failing with “not reachable”.
  • Remote Control reporting a failure when an organization’s policy disables it — it now shows a single quiet notice instead.
  • /mcp reconnect on Remote Control showing a generic withheld-detail error instead of the real remedy when a server was disabled in another session — fixed.
  • Cloud sessions telling Claude the model had changed when the host was only setting the session’s initial model — fixed.
  • Claude apps gateway sessions treating a stored Anthropic profile (e.g. a Console sign-in) as active — fixed; it was listed in /status and used to retry gateway 401s, though requests never use it.
  • SDK and cloud sessions hanging indefinitely when an SDK MCP server’s handshake acknowledgment was lost — the wait now times out after 70 seconds and marks only that server failed.
  • Self-hosted runner leaving a stuck session’s Bash tool processes running after the session was force-stopped — fixed.
  • /usage-credits telling Team and Enterprise members whose admin set the org’s usage-credit limit to $0 that a cap was reached — it now offers to ask the admin instead.

Terminal & CLI

  • Backgrounded sessions (←, /background, --bg) losing a Vertex/Bedrock gateway (ANTHROPIC_*_BASE_URL + CLAUDE_CODE_SKIP_*_AUTH) exported in the shell, so every request failed — fixed.
  • claude --bg --model fable on Max plans stopping to ask for usage credits while the interactive session on the same account still had Fable allowance — fixed.
  • An additionalDirectories entry containing a null byte crashing startup, or breaking /add-dir and later settings updates when it came from an SDK host, IDE, or hook — it is now skipped.
  • Ctrl+G failing with “Emacs quit unexpectedly” in background sessions for editors that open /dev/tty, such as emacs -nw and micro — fixed.
  • The one-time “make auto mode your default” offer appearing in unattended sessions (e.g. agent-team teammate panes), where a stray keypress could accept it unread — fixed.
  • The managed-settings approval prompt re-appearing after signing in again to the same Claude apps gateway when the settings are unchanged — fixed.
  • Disabled /bug and /share reporting that /feedback was disabled — tips, /help, and refusal messages no longer suggest /feedback when an org policy or env var turns it off.
  • claude ultrareview and /ultrareview waiting the full 30 minutes when the cloud session fails to start — they now stop early and report the reason.
  • --worktree --tmux with a merge-request number on a gitlab.com origin trying a doomed GitHub-style fetch first — it now fetches the GitLab ref directly.
  • Italic text (such as the session recap line) rendering as highlighted blocks in GNU screen and in tmux sessions using a screen terminal type — fixed.
  • claude mcp add --header and claude mcp add-json help text naming the wrong transports — fixed.
  • The MCP server menu’s copy shortcut always claiming success — it now says how the sign-in URL was copied.
  • [VSCode] The sign-in screen’s “Bedrock, Foundry, or Vertex” button opening the docs at the top of the page instead of the third-party provider setup section — fixed.

Notes

  • Project settings can no longer relocate config or temp directories — if your project .claude/settings.json env set CLAUDE_CONFIG_DIR, CLAUDE_CODE_TMPDIR, or TMPDIR/TMP/TEMP, it no longer takes effect. Move those to your shell, user, or managed settings.
  • CLAUDE_CODE_SUBAGENT_MODEL no longer wins — it sets the default subagent model, and an agent definition’s model: or an explicit per-spawn model takes precedence over it.
  • Seat-based Enterprise subscriptions default to Opus 5 — matching other premium plans.
  • /effort is now per model — a level you set on one model no longer follows you to another.
  • Six languages lost syntax highlighting — 1c, gml, isbl, mathematica, maxima, and sqf code now renders unhighlighted.
  • Some server-managed settings need approval before they apply — those that terminate sandbox TLS, route sandbox traffic through your own proxy, inject credentials, or weaken sandbox isolation, plus ANTHROPIC_CUSTOM_HEADERS entries that set credential or routing headers.
  • The default commit trailer depends on the active model — when it isn’t a recognized Claude model (e.g. a third-party model behind a custom ANTHROPIC_BASE_URL), the trailer is Co-Authored-By: Claude Code.
  • The /radio command and the footer PR badge reach further — /radio is now available on Bedrock, Vertex AI, Foundry, and Claude Platform on AWS, and with telemetry disabled; in those same setups the PR badge calls the GitHub API directly via gh auth token, GH_TOKEN, or GITHUB_TOKEN.