anthropics / anthropics/claude-agent-sdk-python

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

オープン
#1,255 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
bug
主要言語
Python
スター
8.1k
フォーク
1.3k
平均マージ
2日 31分
マージ済み PR(30日)
1

説明

## 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"]
```

2. **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.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

Start with ClaudeAgentOptions in types.py and inspect _warn_if_can_use_tool_shadowed, then compare _apply_skills_defaults in _internal/transport/subprocess_cli.py. Use the provided SubprocessCLITransport reproduction as the first check; done means both paths accept allowed_tools=None as unset and regression coverage exercises query construction and connect-time behavior.

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
tooling
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
活発
明瞭さ
明確に書かれている
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。