[BUG] Python SDK: `system_prompt` parameter causes `model` parameter to be ignored
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Description
When using claude-agent-sdk with ClaudeSDKClient, specifying any non-None value for system_prompt causes the model parameter to be ignored, resulting in the SDK defaulting to Claude 3.5 Sonnet instead of using the specified model (e.g., Opus 4.1).
Environment
- claude-agent-sdk version: [latest as of January 2025]
- Python version: 3.13
- Claude CLI installed via npm
- Operating System: Linux
Reproduction Steps
Working Code (Uses Opus 4.1 correctly)
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
async def main():
options = ClaudeAgentOptions(
model="claude-opus-4-1-20250805"
# Note: No system_prompt specified
)
async with ClaudeSDKClient(options=options) as client:
await client.query("What model are you and what version?")
async for msg in client.receive_response():
print(msg)
asyncio.run(main())
Output:
I'm Claude, powered by the Opus 4.1 model. Specifically, my model ID is claude-opus-4-1-20250805
Broken Code (Ignores model, uses Sonnet 3.5)
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions
async def main():
options = ClaudeAgentOptions(
model="claude-opus-4-1-20250805",
system_prompt="You are a helpful assistant" # Adding this breaks model selection
)
async with ClaudeSDKClient(options=options) as client:
await client.query("What model are you and what version?")
async for msg in client.receive_response():
print(msg)
asyncio.run(main())
Output:
I'm Claude 3.5 Sonnet, Anthropic's AI assistant, running within the Claude Code CLI interface
Test Matrix
| system_prompt value | Model Used | Result |
|-------------------|------------|---------|
| Not specified | Opus 4.1 | ✅ Works |
| None | Opus 4.1 | ✅ Works |
| "" (empty string) | Sonnet 3.5 | ❌ Bug |
| " " (single space) | API Error | ❌ Error: "text content blocks must contain non-whitespace text" |
| "You are a helpful assistant" | Sonnet 3.5 | ❌ Bug |
Expected Behavior
The model parameter should be respected regardless of whether system_prompt is provided. The SDK should use the specified model (e.g., claude-opus-4-1-20250805) even when a system prompt is included.
Actual Behavior
When any non-None value is provided for system_prompt, the SDK ignores the model parameter and defaults to Claude 3.5 Sonnet.
Workaround
Either:
- Don't include
system_promptin ClaudeAgentOptions when a specific model is required - Explicitly set
system_prompt=None - Include system instructions in the first user message instead
Impact
This bug prevents users from using specific models (like Opus 4.1) with system prompts, which is a common use case for maintaining consistent agent behavior across sessions.
Additional Notes
- The issue appears to be in how the CLI processes the combination of
--modeland--system-promptflags - This affects both streaming mode (
ClaudeSDKClient) and other SDK usage patterns - The bug is consistent and reproducible
Suggested Fix
The SDK should ensure that the model parameter is always passed to the CLI regardless of other parameters, or should throw an error if there's an intentional incompatibility between system_prompt and model selection.
What Should Happen?
Model selection should be respected.
Error Messages/Logs
Steps to Reproduce
See 'what's wrong' section
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.0.8
Platform
Other
Operating System
Other Linux
Terminal/Shell
Other
Additional Information
_No response_
5 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
We are also facing the same issue. For us, haiku is sufficient and we are passing the model as ClaudeAgentOptions. However, during execution ClaudeSDKClient overrides that and invokes sonnet. This shoots up the pricing heavily for us (and without any control).
options = ClaudeAgentOptions(system_prompt=state.get("sys_prompt"),
allowed_tools=["Read", "Write", "Bash", "Edit"],
max_turns=20,
model="claude-3-5-haiku-latest",
cwd=Path.cwd(),
setting_sources=["user"]
)
async with ClaudeSDKClient(options=options) as client:
logger.info("[call_claude_with_tools] Claude SDK client connected successfully")
await client.query(state.get("user_prompt"))
. . . .
Running into the same issue. Have Bedrock model configured and set, with a custom system prompt. The model changes to the default which isn't configured to run. The claude code preset described in https://docs.claude.com/en/api/agent-sdk/modifying-system-prompts works provided there's no append=...
Can you share what version of the Python SDK you're on? There was no SDK in January 2025. Latest should be 0.1.5.
This issue appears to be a model hallucination, not actually a bug in the SDK. I ran @jhargis's example code and got this assistant message response:
Note the
model='claude-opus-4-1-20250805'part of the output there. The issue is that Claude generally doesn't know its own model, so it sometimes hallucinates a model version. We previously defaulted the SDK to use the Claude Code system prompt, but when we renamed to claude-agent-sdk we no longer include that system prompt by default. Claude Code's system prompt includes information about its model number, so you will get an accurate answer if asking CC directly using its normal system prompt. But otherwise Claude is unfortunately just guessing.This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.