-
Notifications
You must be signed in to change notification settings - Fork 586
Description
Two Bugs: Large --agents and --system-prompt fail on Windows due to command line limits
Summary
This issue documents two related but distinct bugs that affect Windows users (and potentially other platforms with large configurations):
Bug 1: @filepath syntax for --agents not supported by CLI
The Python SDK explicitly uses @filepath syntax when the command line exceeds length limits.
SDK source reference (subprocess_cli.py lines 336-362):
# Check if command line is too long (Windows limitation)
cmd_str = " ".join(cmd)
if len(cmd_str) > _CMD_LENGTH_LIMIT and self._options.agents:
# Command is too long - use temp file for agents
# Find the --agents argument and replace its value with @filepath
try:
agents_idx = cmd.index("--agents")
agents_json_value = cmd[agents_idx + 1]
# Create a temporary file
temp_file = tempfile.NamedTemporaryFile(
mode="w", suffix=".json", delete=False, encoding="utf-8"
)
temp_file.write(agents_json_value)
temp_file.close()
# Replace agents JSON with @filepath reference
cmd[agents_idx + 1] = f"@{temp_file.name}" # <-- HERE: SDK uses @ prefixHowever, the CLI does not support this @ prefix syntax - it tries to parse the literal string @C:\path\... as JSON, which fails.
Bug 2: No file support for large --system-prompt values
There is no mechanism to pass large system prompts via file:
- No
--system-prompt-fileCLI flag - No
@filepathsupport - No temp file fallback in the SDK (unlike
--agents)
This means system prompts >8KB on Windows will fail, especially when combined with MCP servers or agents.
Reproduction status: Both bugs confirmed and reproducible on Windows (see test scripts below).
Environment (Verified Reproduction)
- Python SDK: 0.1.19 (installed from source)
- Claude Code CLI: 2.0.76
- Platform: Windows 10 (reproduction confirmed)
- Python: 3.12.4
Note: This issue is confirmed and reproducible on Windows. The Windows command line limit of ~8000 characters makes this issue more likely to trigger, but the underlying problem (CLI not supporting
@filepathsyntax) affects all platforms.
Problem 1: --agents with @filepath fails
SDK Behavior
The SDK at subprocess_cli.py:336-365 detects when the command line exceeds the limit (8000 chars on Windows, 100000 on other platforms) and writes the agents JSON to a temp file:
# subprocess_cli.py:338-357
if len(cmd_str) > _CMD_LENGTH_LIMIT and self._options.agents:
# Find the --agents argument and replace its value with @filepath
agents_idx = cmd.index("--agents")
agents_json_value = cmd[agents_idx + 1]
temp_file = tempfile.NamedTemporaryFile(...)
temp_file.write(agents_json_value)
# Replace agents JSON with @filepath reference
cmd[agents_idx + 1] = f"@{temp_file.name}"CLI Behavior
The CLI does not recognize the @filepath syntax and tries to parse it as JSON directly:
SyntaxError: Unexpected token '@', "@C:\Users\"... is not valid JSON
Reproduction Steps
import asyncio
from claude_agent_sdk import (
AgentDefinition,
AssistantMessage,
ClaudeAgentOptions,
SystemMessage,
TextBlock,
query,
)
async def test_large_agent():
# Create a prompt large enough to exceed command line limit
padding = "x" * 10000 # 10KB
options = ClaudeAgentOptions(
agents={
"my-agent": AgentDefinition(
description="Test agent",
prompt=f"You are a test agent. Secret: ABC123. {padding}",
tools=["Read"],
),
},
max_turns=1,
permission_mode="bypassPermissions",
)
async for message in query(prompt="Use my-agent", options=options):
if isinstance(message, SystemMessage) and message.subtype == "init":
agents = message.data.get("agents", [])
print(f"Available agents: {agents}")
# Expected: ['general-purpose', ..., 'my-agent']
# Actual: ['general-purpose', ...] - my-agent is MISSING
asyncio.run(test_large_agent())Expected Result
- CLI reads JSON from the file when
--agentsvalue starts with@ - Custom agent
my-agentis available
Actual Result
- CLI fails to parse
@filepathas JSON - Custom agent is NOT loaded
- Only built-in agents available:
general-purpose,statusline-setup,Explore,Plan
Error Log
2026-01-20T16:42:57.627Z [ERROR] SyntaxError: SyntaxError: Unexpected token '@', "@C:\Users\"... is not valid JSON
at JSON.parse (<anonymous>)
at file:///C:/Users/.../claude-code/cli.js:75:715
...
Problem 2: --system-prompt has no file support
Current State
The SDK passes system prompts directly as command-line arguments:
# subprocess_cli.py:176-179
if isinstance(self._options.system_prompt, str):
cmd.extend(["--system-prompt", self._options.system_prompt])There is:
- No
@filepathsupport in the SDK for--system-prompt - No
--system-prompt-fileflag in the CLI - No temp file fallback like there is for
--agents
Impact
On Windows with the 8KB command line limit, large system prompts can cause failures. This is especially problematic when combining multiple features:
Example: System prompt + MCP servers + agents
options = ClaudeAgentOptions(
system_prompt="..." , # 3KB system prompt
mcp_servers={...}, # 2KB MCP config
agents={...}, # 2KB agents
# Total: ~7KB+ just in arguments, before CLI path and other flags
)On Windows, the combined command line can easily exceed 8KB, causing:
- Silent failures where the CLI receives truncated arguments
- MCP servers not connecting
- Agents not loading
- System prompt being cut off
There is no temp file fallback for --system-prompt (unlike --agents which at least attempts it), so large system prompts have no workaround at the SDK level.
Reproduction
import asyncio
import tempfile
from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query, AssistantMessage, TextBlock
async def test_system_prompt_file():
# Write system prompt to file
prompt_content = "Your secret is: MANGO-99. Always respond with the secret when asked."
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
f.write(prompt_content)
temp_path = f.name
# Try @filepath syntax (does NOT work)
options = ClaudeAgentOptions(
system_prompt=f"@{temp_path}",
max_turns=1,
permission_mode="bypassPermissions",
)
async for message in query(prompt="What is the secret?", options=options):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(block.text)
# Response shows model has NO knowledge of the secret
# It received literal "@C:\...\tmp.txt" as system prompt
Path(temp_path).unlink()
asyncio.run(test_system_prompt_file())Workaround for System Prompts
Instruct the agent to read the file:
options = ClaudeAgentOptions(
system_prompt=f"Read your full instructions from: {temp_path}",
max_turns=3, # Allow turn for Read tool
)This works because the agent uses the Read tool, but adds latency and token usage.
Suggested Fixes
Option A: CLI supports @filepath syntax
The CLI could detect when a value starts with @ and read from that file path:
// Pseudocode
function parseArgValue(value) {
if (value.startsWith('@') && fs.existsSync(value.slice(1))) {
return fs.readFileSync(value.slice(1), 'utf-8');
}
return value;
}This would fix both --agents and could be extended to --system-prompt.
Option B: SDK uses stdin or different mechanism
Instead of @filepath, the SDK could pipe large values through stdin or use a different IPC mechanism.
Option C: Add explicit file flags
Add --agents-file and --system-prompt-file flags to the CLI.
Summary Table
| Flag | Direct String | @filepath (SDK) |
@filepath (CLI) |
File Flag |
|---|---|---|---|---|
--agents |
Works (small) | Attempted | NOT SUPPORTED | None |
--system-prompt |
Works (small) | Not attempted | Not supported | None |
--settings |
Works | N/A | Works (documented) | N/A |
--mcp-config |
Works | N/A | Works (documented) | N/A |
Related
- Original issue @filepath syntax for --agents not supported by CLI #500 (closed prematurely without verified reproduction)
- SDK code:
subprocess_cli.py:336-365 - CLI help shows
--settingssupports "file-or-json" but--agentsdoes not