Major Updates in Claude Code v2.1.290–v2.1.291 - Enhanced Bash Permission Checks and Change to WebSearch Quota Replenishment Method

Major Updates in Claude Code v2.1.290–v2.1.291 - Enhanced Bash Permission Checks and Change to WebSearch Quota Replenishment Method

Claude Code v2.1.290-v2.1.291 update highlights: WebSearch quota now replenishes over time, and Bash permission checks tested in interactive and non-interactive modes.
2026.10.06

This page has been translated by machine translation. View original

This is Ishikawa from the Cloud Business Division. I'll summarize the Claude Code updates for v2.1.290 ~ v2.1.291 (2026-10-05 ~ 2026-10-06). This article introduces notable updates, and I tried out the Bash permission checks in both interactive and non-interactive modes.

The previous update article is here.

https://dev.classmethod.jp/articles/20261005-cc-updates-v2-1-289/

Update Summary

This covers 2 versions (v2.1.290 ~ v2.1.291, 2026-10-05 ~ 2026-10-06) with a total of 192 changes. The breakdown is 190 changes in v2.1.290 and 2 changes in v2.1.291 (both regression fixes). In my classification, there are 109 fixes, 37 improvements, 27 security items, 12 new features, and 7 breaking changes. The changes include many updates related to Bash permission checks and configuration file handling, as well as fixes for agents view and background sessions.

Notable Updates

WebSearch quota now refills over time (v2.1.290)

The WebSearch quota for interactive sessions has changed from a method that ends at 200 uses to a method that refills over time (100 per hour). The refill rate can be configured with the environment variable CLAUDE_CODE_WEB_SEARCH_REFILLS_PER_HOUR, and setting it to 0 turns it off (original: "0 turns it off"). From the CHANGELOG description, it's not possible to determine exactly what gets turned off (whether it's the refilling or the quota itself).

Note that in v2.1.212, a per-session limit on WebSearch calls was added (default 200, adjustable with CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION). The v2.1.290 CHANGELOG has no mention of how CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION is handled.

For those who continue researching in long interactive sessions, I think it's meaningful that instead of WebSearch becoming unavailable once 200 uses are reached, it becomes available again as time passes.

/claude-api managed-agents-onboard has been added (v2.1.290)

/claude-api managed-agents-onboard has been added. When you pass a URL, it sets up the Managed Agents patterns described on that page as files for use with ant apply. When you pass the name of a Console quickstart template such as deep-researcher, it builds that template with the ant CLI.

For those just getting started with Managed Agents, I think it reduces the effort of initial setup since you can start building the configuration for the ant CLI by passing a page URL or quickstart name.

Fast mode can now be toggled via Claude Tag (Slack) (v2.1.290)

Mentioning Claude in Slack with !fast switches the thread to fast mode (migrating to Opus as needed). Use !fast off to revert, and while enabled, replies will show (fast).

For teams using Claude Tag in Slack, I think this allows switching fast mode per thread, enabling a workflow where you only switch for urgent consultations.

Fixed WebFetch silently truncating pages over 100,000 characters (v2.1.290)

An issue where WebFetch was silently truncating text from pages exceeding 100,000 characters has been fixed. It now communicates the amount of unread content and accepts an offset to read the continuation.

For those using WebFetch to read long API references or specifications, I think it will be easier to notice omissions since the amount of unread content is shown, and you can reduce missed content by using offset to read the rest.

Fixed thinking and prompt cache being lost when resuming sub-agents (v2.1.290)

An issue where resuming sub-agents or teammates that received messages mid-execution would lose their previous thinking and prompt cache has been fixed.

For those who send messages to running sub-agents or teammates mid-execution, I think you can now proceed without worrying about the issue of previous thinking and prompt cache being lost upon resumption.

Fixed the last message of a session being lost on exit (v2.1.291)

A regression introduced in v2.1.288 where the last message of a session could be lost on exit has been fixed.

I think this is a relevant fix for those who want to keep records of the final exchanges in a session.

Fixed Bash permission checks auto-approving some commands (v2.1.290)

An issue has been fixed where Bash permission checks were auto-approving certain read-only commands with arguments that the shell expands as wildcards (such as rg and git grep), as well as certain commands where variable name interpretation differs between zsh and bash. These will now require approval. Additionally, pyright and some ps commands have been changed to require approval before execution (see "Breaking Changes" below).

For those who relied on auto-approval of rg or git grep, I expect that approval confirmations will increase when arguments contain wildcards that the shell may expand.

Fixed permission rules not being applied after PreToolUse hook rewrites input (v2.1.290)

An issue where some permission rules and safety checks were not being applied to a tool call after a PreToolUse hook rewrote its input has been fixed.

For organizations that use PreToolUse hooks to rewrite tool inputs, I think it will be easier to structure operations on the premise that related permission rules and safety checks are applied to the rewritten input as well.

Target Versions and Period

Version Release Date Change Count
v2.1.290 2026-10-05 190
v2.1.291 2026-10-06 2

Update Details

New Features

  • /claude-api managed-agents-onboard <url> and /claude-api managed-agents-onboard <quickstart-name> have been added (see Notable Updates) (v2.1.290).
  • claude attach <name> and claude logs <name> now allow specifying a partial session name instead of a session ID (v2.1.290).
  • A Deny button has been added to the sign-in approval page for Claude apps gateway. Pressing it terminates the pending sign-in and the waiting terminal stops within a few seconds (v2.1.290).
  • The following additions were made for mod/plugin hooks (v2.1.290).
    • agentId has been added to the tool.check event of plugin hooks, enabling distinction between sub-agent permission checks and main session permission checks.
    • ceiling has been added to the question and verdict that mod's tool.check hook reads. This indicates the approval required by the organization for that tool.
    • serverToolUses has been added to the results of mod's turn.step hook. Tool calls executed on the API side (advisor) can be received with id, name, input, start time, and end time.
    • ThemeKey type and Color type have been added to plugin hook type definitions.
    • claude plugin validate now lists each hook registered at gating points by a mod, with .catch presence indicated (as gatingHooks in --json).

Improvements and Changes

  • The WebSearch quota for interactive sessions has changed to a time-based refill method (see Notable Updates) (v2.1.290).
  • Medium effort /code-review now reports cleanup and CLAUDE.md convention issues on models not tuned for review settings (including Opus 5.5 and Sonnet 5.5) (v2.1.290).
  • CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC now also skips connection warm-up at startup (v2.1.290).
  • MCP startup under a network proxy has been improved. It no longer retries 3 times for servers blocked by the proxy (HTTP 403) (v2.1.290).
  • The Read tool message for binary files has been improved to guide Claude toward skills or shell commands capable of reading that format (v2.1.290).
  • Responsiveness during resumption of large sessions has been improved. Timers, input, and rendering now function while the transcript is loading (v2.1.290).
  • The timeout for browser_batch calls in Claude in Chrome has been extended from 60 seconds to 90 seconds (v2.1.290).
  • /model, /effort, and /rename sent to a busy background session via claude agents are now applied immediately without confirmation rather than at the end of the turn (v2.1.290).
  • Background sessions waiting for a scheduled wake-up (/loop) are now kept running even during updates or low memory situations (v2.1.290).
  • Additionally, improvements and changes have been made to Claude apps gateway logs, sign-in pages, certificate expiration warnings, /ultrareview error messages, background daemon log format (multi-line messages output as a single JSON-quoted line), and plugin hook long text handling (v2.1.290).

Fixes (Major)

  • Fixed the last message of a session being lost on exit: This is a regression introduced in v2.1.288. See Notable Updates (v2.1.291).
  • Fixed permission prompt responses being lost in cloud sessions: This is a regression introduced in v2.1.290 (v2.1.291).
  • Fixed requests failing through proxies/gateways: Targets proxies/gateways that reject one of Claude Code's beta headers with a non-400 status, or in combination with another beta header (v2.1.290).
  • Fixed WebFetch truncating text over 100,000 characters: See Notable Updates (v2.1.290).
  • Fixed thinking and prompt cache being lost when resuming sub-agents: See Notable Updates (v2.1.290).
  • Fixed errors in long sessions with many images: Long sessions containing hundreds of images were getting stuck in a "Request rejected as unprocessable by the model" error (v2.1.290).
  • Fixed turns ending immediately on output content filter: When the API's output content filter stopped a response while Claude was thinking, it now retries once before showing an error (v2.1.290).
  • Fixed scheduled tasks not resuming or running extra times: Issues fixed include: interval-based /loop and reminders silently failing to resume after compaction (affecting compaction from v2.1.290 onwards), failing to fire after handoff via ← or /background, and recurring tasks running one extra time per resume/respawn/fork (v2.1.290).
  • Fixed incorrect exit status for --json-schema execution: In headless execution, when the connection dropped after delivering structured output, it was exiting non-zero with is_error: true despite a success result (v2.1.290).
  • Fixed compaction failures: Conversation compaction was sometimes failing with a "null is not an object" error (v2.1.290).
  • Fixed files being deleted during /teleport stash: Selecting a stash with claude --teleport and /teleport was deleting files inside folders that replaced tracked files with the same name. The stash is now rejected with a reason displayed (v2.1.290).
  • Fixed slow startup or failures on SDK hosts: Since 2.1.285, startup could be slow or fail on SDK hosts such as VS Code extensions when managed settings were rejecting reads of many paths on slow filesystems (especially Windows drives under WSL) (v2.1.290).
  • Fixed plan mode not being restored on resume: This occurred when resuming in terminal with --continue or --resume <session-id> (v2.1.290).
  • Fixed AGENTS.md in subdirectories not being attached: This occurred when @ mentioning files under subdirectories (v2.1.290).
  • Fixed background sub-agents losing access to worktree: When the main session entered or exited a different worktree, sub-agents were losing write and Bash access to their own worktree (v2.1.290).
  • A pleasantly surprising fix: An issue where skills could not be found by the name in SKILL.md when the skill's folder name differed from the name in SKILL.md (e.g., non-English names) has been fixed. Both names are now shown in the skills list (v2.1.290). I think this fix will be helpful for those who use Japanese names for skill folders.
  • Additionally, numerous minor bugs have been fixed related to agents view, claude agents, mods/plugin hooks, /ultrareview, Claude apps gateway, behavior on Mac sleep recovery, and more (v2.1.290).

Security

  • Fixed plan mode allowing auto-mode classifier to approve connector tools: Targets non-read-only connector tools granted an ask policy from the server (v2.1.290).
  • Fixed MCP URL rules not applying to some entries: disableClaudeAiConnectors and allowedMcpServers URL rules were not being applied to some MCP entries declared in .mcp.json, plugins, and agents (v2.1.290).
  • Fixed another prompt being approved via permission relay in --channels: Duplicate reply IDs within a session were approving a different prompt. Duplicate IDs are now ignored (v2.1.290).
  • Fixed incorrect auto-approval in Bash permission checks: See Notable Updates (v2.1.290).
  • Fixed Monitor tool in sandbox skipping permission prompts: Monitor tool commands now follow permission rules even under sandbox auto-allow (v2.1.290).
  • Fixed requests being sent to Anthropic under Claude apps gateway: Background commands, agents view, and daemon workers were sending telemetry and feature flag requests to Anthropic when managed settings on the machine did not enforce gateway login (v2.1.290).
  • Fixed background workers following bypass-permissions: Workers were following --allow-dangerously-skip-permissions on respawn even when the bypass-permissions disclaimer had not been approved (v2.1.290).
  • Fixed permission rules not being applied after PreToolUse hook rewrite: See Notable Updates (v2.1.290).
  • Fixed symlinked configuration files being edited without confirmation: Edits to the link target file were being executed without the permission confirmation for configuration files (v2.1.290).
  • Added warnings related to managed settings: Warnings are now shown (in /status and doctor) when a managed settings file is a link to a file outside the managed settings folder, and when allowRead paths or allowed domains configured by the user via sandbox are ignored by managed settings (v2.1.290).
  • Fixed CLAUDE.md and similar files being loaded via symlinks: Project CLAUDE.md, rules, and AGENTS.md that were symlinks pointing outside the working directory were being loaded even under permissions.blockReadsOutsideWorkingDirectories or Read deny rules (v2.1.290).
  • Fixed out-of-scope files being readable by swapping links during read: Targets image reads on macOS/Windows and @ mentions under read blocks or --restricted (v2.1.290).
  • Fixed Read deny rules not applying to paths of pasted images: Also targets filenames listed in @ mentioned folders (v2.1.290).
  • Additionally, many security fixes have been made related to the relationship between mods and organization plugins/guards, commands using variables set with prefixes like declare, short-form options for git clone, filter drivers in /ultrareview, sockets in --restricted sessions, and more (v2.1.290).

Breaking Changes

There are 7 breaking changes, all in v2.1.290. In the before/after examples below, the post-change behavior for pyright was confirmed in my own testing (v2.1.291). All others are based on the CHANGELOG description.

Claude in Chrome can no longer be enabled from project configuration files (v2.1.290)

Claude in Chrome can no longer be enabled from project configuration files. Use --chrome, /chrome, or user settings to enable it. Below are examples of how to enable it.

Before (up to v2.1.289):

# Enable Claude in Chrome from a project configuration file
# → Was effective up to v2.1.289

After (v2.1.290 onwards):

# Cannot be enabled from project configuration files, so use one of the following
claude --chrome   # Flag at startup
/chrome           # Command within a session
# Or enable via user settings

CLAUDE_CODE_DISABLE_ATTACHMENTS can no longer be set from repository configuration files (v2.1.290)

CLAUDE_CODE_DISABLE_ATTACHMENTS can no longer be set from the repository's .claude/settings.json or .claude/settings.local.json. It can still be set from shell, user settings, or managed settings. Below are configuration examples (the value 1 is based on the official documentation's environment variable list).

Before (up to v2.1.289):

# Set CLAUDE_CODE_DISABLE_ATTACHMENTS in repository .claude/settings.json / .claude/settings.local.json
# → Was effective up to v2.1.289

After (v2.1.290 onwards):

# Set via shell (also possible via user settings or managed settings)
export CLAUDE_CODE_DISABLE_ATTACHMENTS=1
claude

Bash tool now requires permission before running pyright and some forms of ps (v2.1.290)

The Bash tool now requires permission before running pyright. pyright is no longer treated as a read-only command. Additionally, more forms of the ps command will require approval rather than running without confirmation (the specific forms are not listed in the CHANGELOG).

Before (up to v2.1.289):

pyright                    → Runs without confirmation as a read-only command
ps (some forms)            → Runs without confirmation

After (v2.1.290 onwards):

pyright                    → Requires permission confirmation before execution
ps (more forms)            → Requires permission confirmation before execution

! shell commands in skills and custom commands are now rejected if they contain control characters (v2.1.290)

! shell commands in skills and custom commands that contain raw control characters other than tabs and newlines are now rejected, and a message showing the position of the control character is displayed. Below is a comparison of behaviors.

Before (up to v2.1.289):

! shell command in skill/custom command (containing raw control characters other than tab/newline)
→ Not rejected

After (v2.1.290 onwards):

Same command
→ Rejected, with a message showing the position of the control character

agent_id in agent results and the firing scope of TeammateIdle hooks have changed (v2.1.290)

In agent results, the agent_id for in-process teammates is now that agent's ID. The name@team address remains in teammate_id. The TeammateIdle hook no longer fires from that teammate's sub-agents or forks. Below is a comparison of behaviors.

Before (up to v2.1.289):

TeammateIdle hook : Also fires from a teammate's sub-agents and forks

After (v2.1.290 onwards):

agent_id          : Agent ID of the in-process teammate
teammate_id       : name@team address (still stored here)
TeammateIdle hook : Does not fire from a teammate's sub-agents or forks

gh api in cloud sessions now rejects non-github.com hosts (v2.1.290)

In cloud sessions, the built-in gh api now rejects setting a non-github.com host via GH_HOST or GH_REPO. Use --hostname or a full URL instead. Requests to other hosts are noted on stderr. Below are command examples (the hostname and API path are placeholders).

Before (up to v2.1.289):

# Specify a non-github.com host via GH_HOST
GH_HOST=ghe.example.com gh api repos/OWNER/REPO

After (v2.1.290 onwards):

# The above is rejected. Specify the host with --hostname
gh api --hostname ghe.example.com repos/OWNER/REPO

VS Code Extension, Claude Tag, Cloud Sessions, etc.

  • [VS Code] You can now view and run plugin marketplace install/update commands from the Manage plugins dialog (v2.1.290).
  • [VS Code] An issue where permission prompts arriving behind an open dialog were stealing keyboard focus, causing keys pressed in the dialog to potentially answer the prompt, has been fixed (v2.1.290).
  • [VS Code] Message timestamps are now shown by default (can be turned off with the Claude Code: Show Message Timestamps setting) (v2.1.290).
  • [Claude Tag] Fast mode toggling with !fast in Slack has been added (see Notable Updates) (v2.1.290).
  • [Claude Tag] An optional Path prefixes field has been added when creating custom connections in access bundles, allowing allow rules to be limited to specified paths rather than the entire host (v2.1.290).
  • [Claude Tag] The channel instruction limit is now 8,192 characters rather than bytes, allowing the same amount of content to be written in non-English text. The character count is displayed next to Save on the Configure page (v2.1.290).
  • Additionally, fixes and improvements have been made to VS Code extension dialogs, agent maps, screen reader support, cloud session working indicators and routines, Remote Control menu display, Claude Tag member permissions and routines, and Code Review comments (v2.1.290).

Testing Bash Permission Checks

Checking behavior in interactive mode

I checked what kind of approvals are requested in interactive mode, which I use daily.

Launch claude with --permission-mode default.

claude --permission-mode default 

From here, I enter prompts in interactive mode to verify behavior.

Please execute the following command exactly once using the Bash tool. Do not use any other tools: pyright --version

Please execute the following command exactly once using the Bash tool. Do not use any other tools: rg TODO *.txt

Please execute the following command exactly once using the Bash tool. Do not use any other tools: rg TODO notes.txt

Verifying behavior details in non-interactive mode

I used claude -p to verify in more detail whether rg with shell-expanded wildcards and pyright now require approval in v2.1.290.

I placed a notes.txt with just a single line TODO: sample line in an empty test directory and asked claude -p to execute the following 3 commands. I specified --permission-mode default to see behavior in default permission mode and limited to 1 turn with --max-turns 1. The third command is for comparison and is rg without a wildcard.

claude -p --max-turns 1 --permission-mode default --output-format json "Please execute the following command exactly once using the Bash tool. Do not use any other tools: pyright --version" > raw1.json
claude -p --max-turns 1 --permission-mode default --output-format json "Please execute the following command exactly once using the Bash tool. Do not use any other tools: rg TODO *.txt" > raw2.json
claude -p --max-turns 1 --permission-mode default --output-format json "Please execute the following command exactly once using the Bash tool. Do not use any other tools: rg TODO notes.txt" > raw3.json

The output extracted from the result JSON with subtype, is_error, and permission_denials.

$ jq '{subtype, is_error, permission_denials}' raw1.json
{
  "subtype": "error_max_turns",
  "is_error": true,
  "permission_denials": [
    {
      "tool_name": "Bash",
      "tool_use_id": "toolu_01GHEhbzuF2tngM5wxixgvxY",
      "tool_input": {
        "command": "pyright --version",
        "description": "Show pyright version"
      }
    }
  ]
}
$ jq '{subtype, is_error, permission_denials}' raw2.json
{
  "subtype": "error_max_turns",
  "is_error": true,
  "permission_denials": [
    {
      "tool_name": "Bash",
      "tool_use_id": "toolu_011Rk4jcDWJDxcs1bEsNqwYD",
      "tool_input": {
        "command": "rg TODO *.txt",
        "description": "Search for TODO in txt files"
      }
    }
  ]
}
$ jq '{subtype, is_error, permission_denials}' raw3.json
{
  "subtype": "error_max_turns",
  "is_error": true,
  "permission_denials": []
}

Since I limited to 1 turn with --max-turns 1, all 3 have subtype of error_max_turns and exit code 1. The is_error being true is also due to termination at the turn limit and is unrelated to permission denial (the third one, which ran without confirmation, is also true). I also checked the tool results returned to Claude, as recorded in the session transcript.

Requested command permission_denials Tool result returned to Claude
pyright --version Recorded This command requires approval
rg TODO *.txt Recorded This command requires approval
rg TODO notes.txt None TODO: sample line

Although pyright is not installed in the test environment, the tool result indicates that approval is required and the command was not executed. rg without a wildcard ran without confirmation and the contents of notes.txt were returned.

Since the test directory contains only notes.txt, the actual files read by both rg commands are the same. Replacing *.txt with an actual filename is done by the shell executing the command, and permission checks are performed against the command string before that — so rg TODO *.txt is evaluated before the files to be read are determined, which is why it requires approval. The CHANGELOG does not state the reason for requiring approval, but I believe it is because it's impossible to determine from the pre-expansion string whether the wildcard would expand to files covered by a Read deny rule or files outside the working directory.

I get a sense that the permission checks are becoming more granular, considering how even seemingly read-only commands are treated differently based on how their arguments will be expanded by the shell. While approval confirmations may increase somewhat, I think the narrowing of what gets auto-approved makes it easier to anticipate what happens when leaving things to auto.

Closing

v2.1.290 had 190 changes, and the next day's v2.1.291 fixed 2 regressions. A regression introduced in v2.1.288 meant that the last message of a session could sometimes be lost on exit, so for those picking up the v2.1.290 changes, I think it's best to update all the way through v2.1.291.

I think it makes sense that Claude in Chrome can no longer be enabled from project configuration files. If you automate claude -p, or conduct long research sessions with WebSearch or WebFetch, why not give it a try?

References

https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md

https://code.claude.com/docs/en/changelog

https://code.claude.com/docs/en/env-vars

https://dev.classmethod.jp/articles/20261005-cc-updates-v2-1-289/


Claudeならクラスメソッドにお任せください

クラスメソッドは、Anthropic社とリセラー契約を締結しています。各種製品ガイドから、業種別の活用法、フェーズごとのお悩み解決などサービス支援ページにまとめております。まずはご覧いただき、お気軽にご相談ください。

サービス詳細を見る

Share this article

AI白書