`allowed_tools=None` raises `TypeError` deep in the transport instead of being treated as unset

Author: tanis90Created Sep 9, 2026Updated Sep 9, 2026
Labelsbug

Describe the bug

Passing allowed_tools=None explicitly is accepted silently by ClaudeAgentOptions (plain dataclass, no validation), then crashes far from the cause — in one of two places depending on configuration:

  1. At query construction (only when can_use_tool is set) — types.py, _warn_if_can_use_tool_shadowed:
python
allowed_tools = options.allowed_tools
if options.skills == _SKILLS_ALL and "Skill" not in allowed_tools:   # TypeError: argument of type 'NoneType' is not iterable
    allowed_tools = [*allowed_tools, "Skill"]
  1. At connect time (always) — _internal/transport/subprocess_cli.py, _apply_skills_defaults:
python
allowed_tools: list[str] = list(self._options.allowed_tools)   # TypeError: 'NoneType' object is not iterable

Reproduced on the latest release (0.2.152) and on current main (both lines unchanged).

To Reproduce

python
from claude_agent_sdk import ClaudeAgentOptions
from claude_agent_sdk._internal.transport.subprocess_cli import SubprocessCLITransport

options = ClaudeAgentOptions(allowed_tools=None)          # accepted silently
transport = SubprocessCLITransport(prompt="hi", options=options)
transport._apply_skills_defaults()                         # TypeError: 'NoneType' object is not iterable

With can_use_tool set it crashes even earlier, at _warn_if_can_use_tool_shadowed(options).

Expected behavior

None is the natural "unset" sentinel for config-driven callers (e.g. options assembled from JSON/YAML, where an absent key yields None). The sibling fields already accept it:

python
tools:            list[str] | ToolsPreset | None = None
skills:           list[str] | Literal["all"] | None = None
setting_sources:  list[str] | None = None
allowed_tools:    list[str] = field(default_factory=list)   # the only one that crashes on None

allowed_tools=None should behave like the default (no --allowedTools flag), consistent with tools / skills / setting_sources.

Environment

  • claude-agent-sdk-python: 0.2.152 (latest release) and current main
  • Python 3.13 (Windows), but the crash is platform-independent

Additional context

Two adjacent notes:

  • The field annotation says list[str] (so None is technically type-invalid), but the dataclass does not validate at construction — the caller gets no early, actionable error, only a TypeError from transport internals at connect time.
  • The related empty-list semantics fix from #523 was closed pointing at PR #638, but #638 is still unmerged and main retains the old truthiness checks — so both that issue's concern and this crash are live on main. This report is narrowly about the None crash; happy to keep the []-vs-unset discussion in #523.

I have a fix ready (widen the annotation to list[str] | None, normalize to [] at the two consumption sites, regression tests for both crash sites) and will open a PR referencing this issue.

Source: anthropics/claude-agent-sdk-python