Skip to content

Commit ab9bcab

Browse files
authored
Fix: omit --setting-sources flag when setting_sources is empty or unset (#778)
## Summary When `setting_sources` was not provided (`None`) or was an empty list, the SDK always passed `--setting-sources ""` to the CLI. The empty string argument causes the CLI argument parser to consume the next flag (e.g. `--permission-mode`) as the `--setting-sources` value, producing: ``` Error processing --setting-sources: Invalid setting source: --permission-mode. Valid options are: user, project, local ``` This blocked all default SDK usage without an explicit `setting_sources` workaround. ## Fix Only add `--setting-sources` when `setting_sources` is a non-empty list, matching the pattern used by other array-typed flags (`allowed_tools`, `disallowed_tools`, `betas`). **Before:** ```python sources_value = ( ",".join(self._options.setting_sources) if self._options.setting_sources is not None else "" ) cmd.extend(["--setting-sources", sources_value]) # always emitted ``` **After:** ```python if self._options.setting_sources: cmd.extend(["--setting-sources", ",".join(self._options.setting_sources)]) ``` ## Testing - Added 3 unit tests verifying the fix: - `test_build_command_setting_sources_omitted_when_not_provided` — no `setting_sources` → no `--setting-sources` flag - `test_build_command_setting_sources_omitted_when_empty` — empty `[]` → no `--setting-sources` flag - `test_build_command_setting_sources_included_when_provided` — `["user", "project"]` → `--setting-sources user,project` - All 427 existing tests pass - Lint clean Fixes anthropics/claude-agent-sdk-typescript#252 <!-- NO CHANGELOG -->
1 parent bd3b7a6 commit ab9bcab

File tree

3 files changed

+37
-14
lines changed

3 files changed

+37
-14
lines changed

e2e-tests/test_agents_and_settings.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ async def test_filesystem_agent_loading():
215215
@pytest.mark.e2e
216216
@pytest.mark.asyncio
217217
async def test_setting_sources_default():
218-
"""Test that default (no setting_sources) loads no settings."""
218+
"""Test that default (no setting_sources) lets CLI load all settings normally."""
219219
with tempfile.TemporaryDirectory() as tmpdir:
220220
# Create a temporary project with local settings
221221
project_dir = Path(tmpdir)
@@ -226,7 +226,8 @@ async def test_setting_sources_default():
226226
settings_file = claude_dir / "settings.local.json"
227227
settings_file.write_text('{"outputStyle": "local-test-style"}')
228228

229-
# Don't provide setting_sources - should default to no settings
229+
# Don't provide setting_sources - CLI uses its default behavior
230+
# which loads all settings (user, project, local)
230231
options = ClaudeAgentOptions(
231232
cwd=project_dir,
232233
max_turns=1,
@@ -235,15 +236,12 @@ async def test_setting_sources_default():
235236
async with ClaudeSDKClient(options=options) as client:
236237
await client.query("What is 2 + 2?")
237238

238-
# Check that settings were NOT loaded
239+
# Check that settings WERE loaded (CLI default loads all sources)
239240
async for message in client.receive_response():
240241
if isinstance(message, SystemMessage) and message.subtype == "init":
241242
output_style = message.data.get("output_style")
242-
assert output_style != "local-test-style", (
243-
f"outputStyle should NOT be from local settings (default is no settings), got: {output_style}"
244-
)
245-
assert output_style == "default", (
246-
f"outputStyle should be 'default', got: {output_style}"
243+
assert output_style == "local-test-style", (
244+
f"outputStyle should be from local settings (CLI default loads all sources), got: {output_style}"
247245
)
248246
break
249247

src/claude_agent_sdk/_internal/transport/subprocess_cli.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,8 @@ def _build_command(self) -> list[str]:
280280
# Agents are always sent via initialize request (matching TypeScript SDK)
281281
# No --agents CLI flag needed
282282

283-
sources_value = (
284-
",".join(self._options.setting_sources)
285-
if self._options.setting_sources is not None
286-
else ""
287-
)
288-
cmd.extend(["--setting-sources", sources_value])
283+
if self._options.setting_sources:
284+
cmd.extend(["--setting-sources", ",".join(self._options.setting_sources)])
289285

290286
# Add plugin directories
291287
if self._options.plugins:

tests/test_transport.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,35 @@ def test_build_command_with_settings_json(self):
389389
assert "--settings" in cmd
390390
assert settings_json in cmd
391391

392+
def test_build_command_setting_sources_omitted_when_not_provided(self):
393+
"""Test that --setting-sources is omitted when setting_sources is not provided."""
394+
transport = SubprocessCLITransport(
395+
prompt="test",
396+
options=make_options(),
397+
)
398+
cmd = transport._build_command()
399+
assert "--setting-sources" not in cmd
400+
401+
def test_build_command_setting_sources_omitted_when_empty(self):
402+
"""Test that --setting-sources is omitted when setting_sources is empty list."""
403+
transport = SubprocessCLITransport(
404+
prompt="test",
405+
options=make_options(setting_sources=[]),
406+
)
407+
cmd = transport._build_command()
408+
assert "--setting-sources" not in cmd
409+
410+
def test_build_command_setting_sources_included_when_provided(self):
411+
"""Test that --setting-sources is included when setting_sources has values."""
412+
transport = SubprocessCLITransport(
413+
prompt="test",
414+
options=make_options(setting_sources=["user", "project"]),
415+
)
416+
cmd = transport._build_command()
417+
assert "--setting-sources" in cmd
418+
idx = cmd.index("--setting-sources")
419+
assert cmd[idx + 1] == "user,project"
420+
392421
def test_build_command_with_extra_args(self):
393422
"""Test building CLI command with extra_args for future flags."""
394423
transport = SubprocessCLITransport(

0 commit comments

Comments
 (0)