← Claude Code changelog

Claude Code 2.1.299

This release introduces automatic idle conversation compaction in the terminal, helping users optimize token usage. Developers gain enhanced mod capabilities, including access to prompt media attachments, detailed session identity, and expanded UI styling. File handling is improved with a new environment variable that controls how file mentions are processed, providing paths instead of contents. The release also delivers numerous critical fixes addressing memory growth, tool execution reliability, issues with image and file attachments, and various display glitches across different session types, significantly boosting overall stability and performance.

Added

  • Added `CLAUDE_CODE_DISABLE_FILE_MENTIONS` environment variable: Claude gets the paths of `@` file mentions to read with its file tools, not the files' contents
  • Added idle compaction in the terminal: a 200K+ token conversation left idle for about 54 minutes is compacted before its one-hour prompt cache expires, so your next message doesn't reprocess it all
  • Added `CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS` to change idle compaction's 200K-token minimum; `"idleCompaction": false` in settings.json turns it off. Both need v2.1.290 or later
  • Added `$.prompt.media` so a `prompt.submit` hook of a mod installed by managed settings can read the bytes of an image or document attached to the prompt
  • Added `$.session.identity()` for mods installed by managed settings: how the session is signed in, and its organization and email when managed `forceLoginOrgUUID` lists that organization
  • Added `size`, `weight`, `mono` and `tabular` to a mod's `Text` and named spacing steps (`xs` to `xl`) to its `Box`; `bold` is deprecated in favor of `weight`
  • Added `--shutdown-drain-sec` to `claude self-hosted-runner orchestrator`: on SIGTERM it stops polling and gives the poll in flight and running spawn hooks up to that many seconds to finish
  • Added the skill's frontmatter, source, plugin name and file path to what a mod's `skill.prompt` hook receives
  • Added `/effort` and `/fast` in agent view to set what new sessions start with; a bare `/model`, `/effort` or `/fast` there now opens a picker
  • Added a "safe mode" line to the agents view peek panel for background sessions started with `--safe-mode`
  • Added a one-time note when plan mode won't ask before most edits or commands because bypass permissions is available
  • Added `--disallow-tools` and a `disallowed_tools` case field to `claude plugin eval` to keep specific built-in tools, such as Agent, out of eval runs
  • Added support for turning off the attribution block in Claude Desktop's Code tab: set `CLAUDE_CODE_ATTRIBUTION_HEADER=0` in the `env` of a Claude apps gateway's `code` policy
  • Added a field to the attribution block in Claude Code sessions behind a Claude apps gateway; remove the block with `CLAUDE_CODE_ATTRIBUTION_HEADER=0`
  • Added a `queue` door to the `session.append` mod hook, so a mod can make the transcript's queue records differ from the prompt as sent
  • Added a note in `/plugin` and `claude plugin validate` naming a mod's hooks that are skipped where an organization manages Claude Code
  • Added `/usage` warnings for max effort, workflows, always-on context and large tool results

Improved

  • Improved the error shown when a cloud session is refused because your claude.ai login was rejected or has expired: it now tells you to sign in again with `claude auth login`
  • Improved enforcement of managed permission rules, managed hooks and organization MCP tool names against user-installed mods
  • Improved memory and disk use when PDFs are @-mentioned: their bytes are no longer kept in the session transcript
  • Improved sandboxed Bash on Linux: Esc and Ctrl-C now work while wildcard read rules are being expanded for a command
  • Improved the startup warning for an unrecognized model ID: it is now one short line under the welcome banner with a docs link, instead of a long raw message
  • Improved the plugin-authoring skill's steps for sharing a mod: Claude asks public or private and checks the files before creating a GitHub repository
  • Improved the Skill tool's "Unknown skill" error to suggest a skill's listed name when Claude wrongly adds the `anthropic-skills:` prefix to it
  • Improved `/reload-skills` to say it re-sends the full skill list to Claude, which is how to get skills back after compaction
  • Improved the error shown when a worktree cannot be created because its base commit does not resolve: it now says how the lookup ended and the likely reasons, such as a repository without a commit
  • Improved the error for creating a worktree at a bare-repository layout's root: it now explains the layout instead of an unrelated git error
  • Improved artifact watching: a local session can now watch up to 25 published artifacts at once, up from 10
  • Improved background agent notifications: they now say when an agent is only waiting on its own background work, got a message too late for its result, or was stopped by a usage limit
  • Improved startup time in workspaces without a Python environment by starting Claude while the Python extension loads
  • Improved startup: the model picker and slash command menu now fill in right away in a new window on a folder you've opened before

Changed

  • Self-hosted runner: Improved what `setup` and `doctor` say when the runner's machine has no git credentials
  • Changed plugin hooks and workflow scripts to refuse values they hand back that nest deeper than 28,000 levels, with an error naming the limit (workflow scripts allowed 100,000)
  • Changed actions a plugin hook can block to be refused, not let through, when the hook cannot be handed them or cannot hand back its answer; a tool that already ran has its result withheld
  • Changed requests to claude.ai's connector proxy and to Anthropic-hosted MCP servers to no longer follow HTTP redirects; redirects by a connector's own server are unaffected
  • Changed MCP requests in cloud and self-hosted runner sessions to no longer follow HTTP redirects from the session's MCP proxy
  • Changed skill and command loading: one whose file or folder name has hidden, direction-changing or blank-like characters, `<` or `>` is no longer offered until renamed; such a `name:` is ignored
  • Changed `ui.render` trees in `claude plugin test`: each mod's Box or Text root now carries `part: { plugin }` naming the mod, so exact-tree assertions must include it
  • Changed WebFetch page reads to pick their effort as web searches do: the caller's level on the caller's own model, otherwise the level settings give the small model
  • Changed `claude plugin test` to fail a call to a mod's served `$` method that has not answered within ten seconds, as a session does
  • Changed MCP allow rules to reach only the server they name: `mcp__a` no longer allows a server named `a__b` or `a_`; write `mcp__<server>__*` with the server's whole normalized name
  • Changed agent `tools:` lists to take only the named MCP server's tools; list a server whose name contains `__` as `mcp__<whole name>__*`
  • Changed Claude in Chrome in Cowork cloud sessions outside auto mode: an approved-site action the safety classifier flags now asks you instead of being refused, unless managed settings apply
  • Changed cloud session and Remote Control MCP connectors to negotiate MCP protocol version 2026-07-28 by default on installs that fetch no flags; `MCP_PROTOCOL_NEGOTIATION=legacy` opts out
  • Changed MCP tool descriptions and server instructions from Anthropic's first-party MCP servers at `api.anthropic.com` to reach Claude in full instead of being cut at 4,096 characters
  • Changed auto mode in Cowork cloud sessions: a `PermissionRequest` hook can no longer approve shell commands or subagents; those prompts wait or are denied
  • Changed the resume command printed at exit: it names the session by its ID and no longer by its name, so that nothing in a session name can run when the line is pasted
  • Changed the resume command printed at exit of a worktree session: it uses `-w` and `-r` if the long flags do not fit the terminal. If neither fits a kept worktree, rows above it say where to run it
  • Changed `/btw` side questions in non-interactive sessions to return a timeout error when still unanswered after 11 minutes
  • Changed `UserPromptSubmit` hooks to run before a skill or custom slash command expands, so a hook that blocks the prompt now also stops its embedded shell commands
  • Changed a skill's own front-matter `UserPromptSubmit` hook to first run on the prompt after the one that invokes the skill
  • Changed the `turn.start` mod hook to also hear subagents' and teammates' turns, not only the main loop's; tell them apart by `e.agentId` (absent on the main loop)
  • Changed the errors shown when `/ultrareview` can't upload a repository to stop suggesting `git add .`, which could stage or commit untracked files such as `.env`
  • Changed the cyber safeguard notice to no longer ask people to apply to the Cyber Verification Program
  • [Cloud sessions] Improved the deploy command shown when you create a self-hosted environment or environment key: it shows in full, wraps between arguments, and has a visible copy button
  • [Cloud sessions] Changed deleting a self-hosted environment to turn off its routines right away, with the reason shown on each routine, instead of leaving their runs to fail
  • [Claude Tag] Added the ability for Claude in Slack to delete a canvas it created in a channel when someone asks it to
  • [Claude Tag] Changed how Claude in Slack corrects a message it got wrong: it edits the message in place and adds a short "Edited" note instead of striking through the old text
  • [Claude Tag] Changed Claude in Slack to join channels with more than 100 members quietly, with no intro message

Fixed

  • Fixed the error for a denied cloud session, which could point to the wrong organization when a key from `apiKeyHelper` was in use
  • Fixed sessions on a gateway-specific model name behind a custom `ANTHROPIC_BASE_URL` ending with "Prompt is too long · automatic compaction failed" near 200K tokens instead of sending the request
  • Fixed a mod that submits a prompt at the end of every turn keeping a headless run going past `--max-turns`, `--max-budget-usd`, an interrupt, or the end of the host's conversation
  • Fixed cloud sessions sometimes showing the model's follow-up text after a tool group's one-line label
  • Fixed the Write and Edit tools creating a mod in a session's mods folder without asking in accept-edits mode when the config directory's path has no `.claude` in it
  • Fixed installed mods that kept running in an open session after being turned off remotely; they now unload between turns
  • Fixed Edit and Retry in Cowork and claude.ai cloud sessions failing on a message stopped while its `UserPromptSubmit` or mod `prompt.submit` hooks were still running (regression in 2.1.296)
  • Fixed an agent teammate started without a description keeping part of a credential from its prompt in the task description shown for it
  • Fixed the claude.ai view of a Remote Control or cloud session freezing when a large batch of events could not finish uploading over a slow connection
  • Fixed a sandboxed shell command being able to write into a `--plugin-dir` folder, whose code Claude Code reloads and runs outside the sandbox
  • Fixed memory growth under heavy debug logging (`--debug`, `--debug-file`), and a hang on exit when the debug log is on a disk or network mount that stops accepting writes
  • Fixed memory growing without bound when debug output goes to stderr and the parent process stops reading it
  • Fixed rm prompts on shell `-c` scripts that don't run `rm`. An rm built at run time in a script Claude Code can't read no longer prompts unless `CLAUDE_CODE_STRICT_INLINE_SHELL_RM_PROMPT=1`
  • Fixed double-clicking a word in an expanded transcript row in fullscreen mode collapsing the row instead of selecting the word
  • Fixed `claude mcp list`, `claude doctor` and `/status` reporting an empty `.mcp.json` as invalid
  • Fixed `/btw` jumping the transcript to the bottom when asked while scrolled up in fullscreen
  • Fixed sandboxed commands failing on WSL2 with `bwrap: Can't mkdir /mnt/c/Program Files/ClaudeCode` when the sandbox can write to the Windows drive
  • Fixed scheduled wakeups (ScheduleWakeup) not firing while a background task was running in Agent SDK, IDE and `claude remote-control` sessions
  • Fixed a mod's `prompt.submit` rewrite being silently dropped, sending the prompt as typed, for some prompts with a pasted image or an image that can't be read
  • Fixed a Remote Control prompt being lost when another queued prompt in the same batch failed to deliver
  • Fixed a Remote Control prompt that had passed its hooks being dropped from prompt history when Stop interrupted the next queued prompt's hook
  • Fixed sign-in, MCP servers and project trust appearing lost on Linux after a sandboxed command left an empty `.config.json` in the config directory
  • Fixed `/sandbox` reporting success when its setting could not be saved because the project folder is not writable; it now says nothing changed and why
  • Fixed SDK and headless sessions staying in auto mode after the host switched to a model that doesn't support auto mode
  • Fixed MCP servers named `constructor` or `prototype` in an MCP config never being connected
  • Fixed tools of an MCP server named `constructor` or `toString` asking for permission in auto mode and bypass permissions mode
  • Fixed a spurious "synced[0] commands path not found" plugin error at startup when another Claude Code process had just updated a claude.ai-synced plugin
  • Fixed the Artifact tool advising a retry when a publish that requests connectors or other access was refused by the server or a proxy (HTTP 403); it now says so and what to tell the user
  • Fixed Cowork cloud sessions staying on an old account plugin after a plugin reload that timed out or a restart that reused a recent sync
  • Fixed document blocks being dropped from your own message sent while Claude is working
  • Fixed Claude in Chrome asking for permission while no browser is connected; it now says the extension is not connected
  • Fixed the fullscreen "Update installed" notice being hidden behind the idle "/clear to save tokens" hint; it now shows beside the hint
  • Fixed a mod hook, with or without a `.catch`, being run again without end when it waits on another mod's noun that does its work outside the call
  • Fixed the Claude apps gateway serving models that a policy's `availableModelsMatch: exact` or `deniedModels` blocks; it now answers 400 and leaves them out of its model lists
  • Fixed the server-managed settings request to Anthropic carrying a third-party gateway's API key when a managed settings file sets `ANTHROPIC_BASE_URL`
  • Fixed streams through a custom `ANTHROPIC_BASE_URL` being aborted after 180 seconds with no data arriving; they now wait 300 seconds, whether or not feature flags are loaded
  • Fixed a mod's `tool.describe` or `prompt.section` answer that changed after `$.ui.invalidate` never reaching Claude; the new answer is now sent on the next turn
  • Fixed a settings file being ignored when `enabledMcpjsonServers` or `disabledMcpjsonServers` held a single server name (letters, digits, - or _) as a plain string
  • Fixed `claude plugin test` pausing a hook's time budget while a served `$` method it had called kept making `$` calls after answering
  • Fixed high memory use after resuming a cloud or Remote Control session that had run many subagents
  • Fixed plugin hooks being skipped when they pass a very deeply nested tool input or message on with next()
  • Fixed a value a mod's hook passes to `next()`, returns, or sends to a `$` method being refused whole when one of its getters throws a `RangeError`; now only that key is refused
  • Fixed `/usage`, the approaching-limit warning (terminal and VS Code) and the status line sometimes showing more than 100% used (anthropics/claude-code#92238)
  • Fixed wrapped text mixing CJK or emoji with Latin words losing its last line or leaving a blank row at some terminal widths
  • Fixed a cloud session sometimes ignoring the answer to a permission prompt or a question when the answer was given while the session's worker was being replaced
  • Fixed bold, italic and other nested text styles running over table borders or being lost on wrapped rows
  • Fixed Cowork cloud sessions running the old version of an account plugin changed, removed or disabled from another device until the session restarted
  • Fixed deny and ask rules for an MCP server (`mcp__<server>`) not applying when the server's normalized name contains a double underscore
  • Fixed long conversations losing newly attached images on every turn after one oversized image was refused by the API
  • Fixed the `plugin_loaded` telemetry event reporting `has_hooks` as false for plugins whose hooks are a hooks module, built-in plugins included
  • Fixed images attached while Claude is working (VS Code, desktop app, SDK) being sent at full size, which led to repeated image errors in long conversations
  • Fixed the image coordinate hint being missing or slightly off for large near-square images on newer models
  • Fixed feature flag, startup, fast mode, profile and feedback requests to Anthropic carrying the API key configured for a third-party gateway (`ANTHROPIC_BASE_URL`); Anthropic API keys are still sent
  • Fixed a mod's hot reload ignoring a fix saved right after a failed reload; saving a mod file without changing it no longer reloads the mod
  • Fixed mods loaded from source files being refused when a hook hands `$` to a function declaration imported from another file of the mod
  • Fixed a regression in 2.1.296 where cloud and headless sessions could run an approved tool call twice if a new message arrived as the session resumed after a restart
  • Fixed scheduled tasks being announced for the wrong minute: the scheduling tools now report each job's actual next run time
  • Fixed mods' hooks being handed values with `__proto__` keys silently removed, which could skip a `tool.check` guard on a tool call another mod made
  • Fixed `claude -p` saying nothing when a settings file fails validation: text-output runs now list the file and the invalid entry on stderr
  • Fixed long pastes in terminals without bracketed paste losing all text after an invisible control character, such as a mis-decoded curly quote
  • Fixed managed settings and organization policy not being fetched when the stored login's plan was changed locally on machines whose MDM or managed-settings file sets `forceLoginOrgUUID`
  • Fixed MCP connections over HTTP hanging for 30 seconds and failing when a server never ends the body of its reply to a notification (anthropics/claude-code#99014)
  • Fixed MCP servers added to a running headless or SDK session being connected before some policy checks ran; a blocked server is now reported as failed without being contacted
  • Fixed `claude mcp list`, `claude mcp get` and subagent MCP servers starting a server that a policy check blocks; it is now reported as blocked without being started
  • Fixed `/reload-plugins` not loading a plugin installed from another terminal a moment earlier
  • Fixed blank rows appearing under CJK and emoji text squeezed into a one-cell column, as in a very narrow terminal
  • Fixed text cut in the middle beside wide characters leaving a cell unused or being cut twice, and an emoji vanishing where a color changed inside it
  • Fixed bare mode notices in background sessions telling you to restart without `--bare`, which keeps the mode; they now name `/stop` and `claude --resume`, as safe mode ones do
  • Fixed `←` not saying why it stayed put over a queued message while Remote Control is on
  • Fixed `$.http.fetch` in mods refusing a `304`, `204` or `205` response that declares a `Content-Length` over the 4 MiB body limit
  • Fixed `/config` push notification toggles sending your account the previous setting instead of the one you just chose
  • Fixed a cloud session leaving a reply unfinished when its worker was replaced just after the reply hit the output token limit
  • Fixed Read failing on PDF page ranges in remote sessions on Linux that run without elevated privileges
  • Fixed Enter answering a question or permission prompt that had been held back while you typed an unsent message
  • Fixed a file attached to a message in a remote session being left out when its download stalled part way; the download is now tried again
  • Fixed queued prompts sent as content blocks over `--input-format stream-json` running together without a line break when merged into one turn
  • Fixed self-hosted runner sessions shutting down MCP servers added through an `--exec-path` wrapper's own `--mcp-config` when connectors change mid-session
  • Fixed `claude plugin eval` passing runs that the API refused: a run that ends on an API error now scores 0 without grading and makes the suite exit 1
  • Fixed permission prompts cutting off or wrapping too early when the reason text contains keycap or joined emoji
  • Fixed `forceLoginOrgUUID` and `forceLoginMethod` from MDM or the managed-settings file being hidden or replaced by server-managed settings
  • Fixed `--bare` sessions leaving out an MCP server named `constructor` or `prototype` that `--channels` asked for
  • Fixed resuming a conversation from before `/clear` reattaching to the Remote Control session of the conversation after it
  • Fixed a prompt starting with `/`, sent with the Agent SDK's `verbatimPrompts` option, running as a slash command when `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` re-ran it after a restart
  • Fixed background sessions started with `--safe-mode` silently leaving safe mode when the session was woken or restarted
  • Fixed scheduled tasks and loops firing again after every turn, or firing early, during the repeated hour when daylight saving time ends
  • Fixed the diff view listing a new file whose name begins or ends with a space under the wrong name
  • Fixed MCP tool calls in headless and SDK sessions sometimes failing or running twice when a background reconnect closed the connection they were running on
  • Fixed `/btw` side questions in non-interactive sessions not being cancelled when the session ends, and running a second time when the same request arrived again mid-run
  • Fixed sandboxed commands on macOS being able to read or write a denied path by its real location when the denied path passes through a symlink
  • Fixed sandbox `denyRead` and `allowRead` globs with braces, parentheses or backslashes in a folder's name being read differently by Claude Code's settings checks than by the sandbox
  • Fixed sandbox glob `allowRead` and `allowWrite` entries not being re-checked when the directory they start from is replaced by a symlink
  • Fixed worktree-isolated sessions accepting some awk programs the isolation guard should refuse
  • Fixed `claude mcp add <name> -- <command> --background` being started as a background session
  • Fixed a prompt or reply of `--bg` or `--background` to a background session being taken for the flag, which could start new sessions over and over instead of delivering it
  • Fixed a custom slash command's embedded shell line running twice when a newer message interrupted the command while its prompt was being checked
  • Fixed `--worktree` sessions leaving a folder behind in `.git/worktrees` in repositories using git's reftable ref storage
  • Fixed `claude self-hosted-runner` sessions using Anthropic-managed git showing tracked files as staged deletions when starting in a reused clone whose remote is still empty
  • Fixed Ultracode not being announced to scheduled tasks and other delivered headless turns when `ultracode` is on in settings
  • Fixed MCP OAuth sign-in, token refresh and sign-out not sending configured `headers`/`headersHelper` values, which broke servers behind an authenticating proxy
  • Fixed the Artifact tool reporting a spurious one-line difference against the live page, and refusing the publish, when a large page with a line break after `<head>` is published again unchanged
  • Fixed `$.ui.open` reporting a mod's pane as placed in sessions where no surface draws it, such as Claude Code for VS Code and `claude -p`
  • Fixed the `agent.spawn` mod hook not running when a finished subagent or a killed teammate is resumed: the hook's event now carries `resume`, and a mod can refuse it
  • Fixed `claude plugin validate` rejecting a mod's `$.state` references when `plugin.json` has no `types` key and the contract is at `./types/index.d.ts`
  • Fixed a mod's `dimColor` text looking the same as plain text under the dark ANSI theme and on 16-color terminals
  • Fixed plan mode running a write (an MCP tool's, a file's, a shell command's) that a `PreToolUse` hook or a mod's `tool.check` hook allowed
  • Fixed background subagents in auto mode sometimes sending their final report twice, once as the result and once as a message
  • Fixed `SendMessage` not finding a subagent by name after the CLI restarted and resumed the session (names given before the last compaction still need the agent ID)
  • Fixed replies cut off at the output token limit ending the turn silently, with no retry or error, after a request fell back to non-streaming mode
  • Fixed Read garbling UTF-16LE files with a byte-order mark, and Write dropping byte-order marks or silently converting Windows-1252, Shift-JIS, GBK or UTF-16BE files to UTF-8 (now refused)
  • Fixed cloud sessions sometimes leaving a message unanswered when the worker was replaced right after a compaction
  • Fixed cloud sessions and `CLAUDE_CODE_RESUME_INTERRUPTED_TURN` sometimes answering a finished turn again after a restart, when a tool ended the turn and a skill loaded in the same step
  • Fixed photos sent over Remote Control being dropped when their copy could not be saved on your computer; Claude now still sees the photo
  • Fixed files sent over Remote Control sometimes not arriving in long-running sessions
  • Fixed files of 30 to 35 MiB sent over Remote Control or to a cloud session not arriving
  • Fixed a user-installed mod's `$.env.set` changing the environment or shell prefix that command hooks from managed settings start with
  • Windows: Fixed the process-liveness check leaving orphaned PowerShell processes behind on busy machines until memory ran out
  • Windows: Fixed PreToolUse and PermissionRequest hooks that set no shell failing open when Git for Windows isn't installed; a guard that fails now blocks the call
  • Windows: Fixed Bash commands failing with "command not found" for a whole session when Git Bash did not report its PATH at startup
  • Self-hosted runner: Fixed sessions that wrote output before their first turn being left with no release timer, ignoring `--retire-at` and delaying shutdown
  • Fixed an unsent prompt and its attachments being lost when switching to another session and back
  • Fixed unused blank chats keeping a background Claude process running after starting a new conversation
  • Fixed the mic button showing an internal error message when you are signed out of claude.ai; it now offers to sign you in
  • [Cloud sessions] Fixed a memory spike that could crash a session when many of its existing output files were re-sent to it at once
  • [Cloud sessions] Fixed saving an edited routine silently moving it to a different environment when its own had been deleted or wasn't in the list; the routine now keeps its environment
  • [Cloud sessions] Fixed Sessions search in a self-hosted environment's admin details finding nothing when you paste the session ID from a session's link
  • [Cloud sessions] Fixed the Sessions and Runners lists in a self-hosted environment's admin details saying the list is empty when a search just has no matches
  • [Remote Control] Fixed Remote Control sessions whose computer can't be reached still appearing to send your messages; your text now stays in the box and Send is off until it reconnects
  • [Claude Tag] Fixed Claude in Slack staying silent on untagged posts that a channel's own instructions tell it to answer, such as posts that tag someone else, in channels with guests
  • [Claude Tag] Fixed Claude in Slack reporting a reply to another channel's thread as posted when it isn't a member there; it now says the reply wasn't delivered and how to fix that
  • [Claude Tag] Fixed Claude in Slack sometimes ending a turn without posting its answer when a self-hosted runner's image has no python3
  • [Code Review] Fixed Code Review's monthly spend-limit comment and check-run card sending admins to Claude Code settings; they now link the Usage page, where that limit is set