Claude Code 2.1.310: Gateway Retries and Windows Hook Fixes
Upgrade the active Claude Code binary, identify effort beta and mid-conversation system rejections, and verify that Windows hooks block failed interpreters. Replace extreme cleanupPeriodDays settings with a deliberate retention policy, preserve surviving attachments, and understand the limits of retries and file recovery.
Contents

If Claude Code fails through a gateway with Unexpected value(s) naming effort-2025-11-24, or with Unexpected role "system", upgrade to 2.1.310 or later and retry the affected conversation. Windows teams should also test whether a failed hook interpreter actually blocks a tool call. If an extreme cleanupPeriodDays setting coincides with missing pasted images, preserve surviving data before changing retention.
As of 2026-10-25, the official 2.1.310 release notes confirm fixes for these gateway, Windows hook, and cleanup cases. The procedures below address each failure separately.
Verify that the active executable is 2.1.310 or newer
Check the executable your terminal launches, then update through the installation method you already use. In Bash, or unchanged in Windows PowerShell, run:
claude --version
claude doctor
claude doctor provides read-only installation and settings diagnostics. Keep the version output so you can compare it after updating.
Use the matching command from Anthropic’s installation and update instructions:
| Existing installation | Shell | Update command |
|---|---|---|
| Native installer | Bash or PowerShell | claude update |
| Homebrew stable cask | Bash | brew upgrade claude-code |
| Homebrew latest cask | Bash | brew upgrade claude-code@latest |
| WinGet | PowerShell | winget upgrade Anthropic.ClaudeCode |
| npm | Bash or PowerShell | npm install -g @anthropic-ai/claude-code@latest |
Native updates follow the configured release channel. Homebrew’s claude-code cask follows stable, while claude-code@latest follows latest; an update can therefore finish successfully while leaving you below the required version.
For an existing native installation, the CLI also supports installing a specific version with claude install 2.1.310. For a package-managed deployment, select a package or channel that supplies the required version through that deployment’s normal process.
Run claude --version again, then start a fresh Claude Code session. If the version remains old, check for conflicting installations with which -a claude in Bash or where.exe claude in PowerShell. An editor’s terminal may also need the editor itself restarted to pick up a changed PATH.
Match the gateway error to the supported retry
Use the returned error text to choose the fix. A generic 400 does not identify which capability the gateway rejected.
Anthropic’s gateway compatibility guide documents these recovery paths:
| Response signature | Automatic fallback | What to check |
|---|---|---|
400 starting with Unexpected value(s) and naming effort-2025-11-24 for anthropic-beta | Omits the effort field and beta for that model until Claude Code exits. | Remove this value if you manually added it to ANTHROPIC_BETAS. |
400 naming output_config.effort with Extra inputs are not permitted, or saying effort is unsupported | Uses the effort fallback. | Confirm that effort is the rejected field. |
400, for example Unexpected role "system" | Moves mid-conversation system text into user messages; keeps that format until /clear or compaction. | Retry the affected conversation. |
The fallback changes the request. The effort parameter controls how the model spends tokens, so a successful retry without it does not establish that your requested effort setting was honored. Likewise, moving system text into user messages preserves text while changing its representation.
Reproduce the failing conversation
Keep the same gateway, credential source, and selected model while checking the upgrade. This makes the comparison useful: changing providers and versions together would leave the cause unclear.
First, start Claude Code and run /status. The gateway connection instructions explain how to confirm the active base URL and credential source there. If the intended gateway is absent, fix that configuration before investigating its beta support.
Then exit and reopen the affected conversation with a local diagnostic log. In Bash:
claude --resume --debug-file ./claude-gateway-debug.log
Choose the failed session from the picker and repeat the smallest request that reproduces the problem. These flags are documented in the CLI reference.
The immediate success check is a usable assistant response where the previous request failed. To establish that the compatibility fallback caused recovery, inspect the available client diagnostics and, where available, the gateway’s request diagnostics for the rejection followed by an adjusted retry. A successful first prompt in a new conversation does not exercise every later conversation shape.
For BetterToken, its Claude Code setup specifies ANTHROPIC_BASE_URL=https://bettertoken.ai without /v1; keep that documented route while checking the client upgrade.
If the upgraded client still fails
Preserve upstream error bodies: replacing a recognizable rejection with an opaque gateway error can prevent fallback detection. Also, CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 retains effort and mid-conversation system entries, so it is not a universal switch for these failures.
Use the next action that matches the remaining evidence:
- The same recognized rejection repeats: check the active binary, manually supplied beta values, and whether the gateway rewrites the upstream error.
- Authentication fails: follow the gateway’s credential instructions. The connection guide distinguishes
ANTHROPIC_AUTH_TOKENfor Bearer authentication fromANTHROPIC_API_KEYforx-api-key; use the scheme your provider documents. - The error names another field: investigate that field’s compatibility requirements. Do not classify every schema rejection as the effort bug.
- The connection fails before an API response arrives: investigate the endpoint, proxy, DNS, or TLS path.
For an escalation, collect the client version, operating system, selected model ID, request time or request ID, HTTP status, and exact error. Share a redacted diagnostic excerpt rather than credentials or a complete conversation log.
Make Windows hooks prove that they block
Upgrade through 2.1.310, then test the failure path of any hook you rely on for policy enforcement. The adjacent releases cover different cases:
- 2.1.309 fixes PowerShell hook exit-code handling and missing-Git failures when hooks explicitly select PowerShell.
- 2.1.310 fixes the additional missing-Git-Bash case where the hook command contains only quoted strings.
A hook error is not automatically a denial. The hooks reference provides onFailure: "block" for command and HTTP hooks that must stop the triggering action when they fail.
Check the quoted-command regression
Use a disposable native Windows test environment without Git Bash, with a working Claude Code connection and no unrelated hooks or plugins affecting the result. This checks the missing-Git-Bash path without removing Git from your working machine.
In PowerShell, create a fresh probe directory and a harmless file:
$hookProbe = Join-Path $env:TEMP ("claude-hook-probe-" + [guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Path (Join-Path $hookProbe '.claude') -Force | Out-Null
Set-Location $hookProbe
Set-Content -LiteralPath .\probe.txt -Value ([guid]::NewGuid().ToString())
Test-Path 'C:\__claude_hook_probe_missing__\python.exe'
claude --version
Test-Path must return False, and the version must be at least 2.1.310.
Create .claude/settings.local.json in this probe directory with:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Read",
"hooks": [
{
"type": "command",
"command": "\"C:\\__claude_hook_probe_missing__\\python.exe\""
}
]
}
]
}
}
The omitted shell, args, and onFailure fields are deliberate: this phase examines the quoted-command fallback itself.
Start the session in PowerShell:
claude --tools Read --debug-file .\phase1.log
Accept workspace trust for this disposable directory, then run /hooks and confirm that the PreToolUse hook matches Read. Ask:
Use the Read tool exactly once to read probe.txt. If the call is blocked, report that and stop. Do not use another method.
Expected result: the Read call is blocked, with PowerShell started no program in the error or diagnostics. PowerShell normally evaluates a quoted path as a string; Microsoft’s call-operator documentation explains why invoking that path requires different syntax.
An actual successful Read result fails this check. If Claude never attempts Read, the result is inconclusive. Inspect the tool result and log rather than accepting the model’s description as proof.
If /hooks does not list the configuration, follow the hook-loading checks. Settings normally reload automatically, but restarting forces a reload if the file watcher missed the change. A managed policy allowing only managed hooks also means this project-level probe has not run.
Check a genuinely missing interpreter
Use an explicit failure policy to test what happens when the interpreter cannot start. Exit the probe session and replace only the inner hook object with:
{
"type": "command",
"command": "C:\\__claude_hook_probe_missing__\\python.exe",
"args": [],
"onFailure": "block"
}
Here, args selects direct executable invocation. The missing executable now causes a real launch failure rather than a quoted-string expression.
Restart in PowerShell and repeat the same Read prompt:
claude --tools Read --debug-file .\phase2.log
Expected result: Read is blocked because the interpreter failed to start. This checks explicit failure handling independently of Git Bash availability; it is a different check from the quoted-command regression.
After reviewing the results, remove the probe configuration. In real policy hooks, restore the functioning interpreter and retain an explicit blocking failure policy where a failed check must stop the action.
These probes exercise PreToolUse. A PermissionRequest hook needs a separate check using an action that reaches the permission stage. Its normal denial uses hookSpecificOutput.decision.behavior set to "deny"; exit code 2 alone does not deny that event. An actual failure with onFailure: "block" does deny the request.
Replace extreme retention values deliberately
Use the documented default of 30 days unless your team has a specific retention requirement, and archive wanted history before shortening an existing period.
The cleanup fix addresses recent-file deletion associated with extremely large cleanupPeriodDays values. It does not turn the setting into an archival system or restore files already removed.
Preserve surviving data before changing the cutoff
Stop active sessions and copy data you still need to storage outside Claude Code’s managed directories. Include the relevant ~/.claude data, or %USERPROFILE%\.claude on Windows, together with surviving image attachments.
Current application-data documentation places newer pasted images in per-session images/ directories beneath Claude Code’s temporary root, controlled by CLAUDE_CODE_TMPDIR. Backing up only ~/.claude therefore does not establish that current image copies were preserved.
After preservation, merge this setting into the appropriate settings file:
{
"cleanupPeriodDays": 30
}
For a personal default, that file is ~/.claude/settings.json, or %USERPROFILE%\.claude\settings.json on Windows. Preserve its other keys.
As documented on 2026-10-25, the minimum is 1; 0 fails validation. Lowering the period makes older data eligible for cleanup, which is why preservation comes first.
Run claude doctor to check settings validity. If the intended value does not apply, inspect settings precedence: managed settings and higher-priority session or project settings can override your personal file. /status shows loaded sources, not a winning value for every individual key.
Recover missing attachments separately
Restore a missing image from its original file or an existing filesystem backup, then attach that recovered copy to the conversation. Verify that the file opens locally and that Claude can use the attachment again.
Changing the retention setting cannot reconstruct deleted bytes. Nor should you assume /rewind will recover an attachment: checkpoint snapshots also expire, and restoration can fail when the required snapshots are gone.
For teams already exporting telemetry, inspect a completed claude_code.retention_sweep event. The monitoring reference documents result: "complete" and a string-valued period_days; "30" confirms that particular sweep used 30 days.
A brief restart is insufficient to prove cleanup ran. The sweep runs in the background at most once per session, and a sweep during the preceding 24 hours delays the next session’s sweep by at least 10 minutes. Treat attachment readability and evidence of a completed sweep as separate observations.
Monitor availability is a separate change
Version 2.1.310 also extends the Monitor tool and plugin monitors to Bedrock, Vertex, and Foundry, including configurations with telemetry or nonessential traffic disabled. The release notes also say long foreground sleeps are blocked there.
If Monitor was missing in one of those deployments, check the running version before changing telemetry policy. That availability change is separate from whether a particular gateway accepts effort settings or mid-conversation system entries.