When you use Anthropic’s extended thinking mode in the Claude SDK and try to access config.budget_tokens, Python raises AttributeError: 'ThinkingConfigEnabled' object has no attribute 'budget_tokens'. The fix is simple once you know the reason: the SDK expects a dict literal, not a constructor call. Here is the exact fix, why it happens, and how to avoid it in production.

Why the AttributeError happens
Anthropic’s SDK ships ThinkingConfigEnabled as a TypedDict, not a full Python class with attribute access. When you write ThinkingConfigEnabled(type="enabled", budget_tokens=16000), Python creates the object but the resulting instance does not expose .budget_tokens as an attribute. It only exposes dictionary keys.
The recommended pattern in 2026 is to pass a dict literal directly. This works because the SDK does its own key validation and never needs attribute access on the config object.
The fix: use a dict literal
import anthropic
client = anthropic.Anthropic()
# WRONG (raises AttributeError when SDK accesses .budget_tokens internally)
# from anthropic.types import ThinkingConfigEnabled
# thinking = ThinkingConfigEnabled(type="enabled", budget_tokens=16000)
# CORRECT (2026 recommended pattern)
message = client.messages.create(
model="claude-opus-4-8",
max_tokens=32000,
thinking={
"type": "enabled",
"budget_tokens": 16000
},
messages=[{"role": "user", "content": "Solve this problem step by step"}]
)
for block in message.content:
if block.type == "thinking":
print("Reasoning:", block.thinking)
elif block.type == "text":
print("Answer:", block.text)Debugging checklist
- Confirm your Anthropic SDK version:
python -c "import anthropic; print(anthropic.__version__)". Extended thinking requires SDK 0.42+ from 2026. - Confirm the model supports thinking. Only Opus 4.8+, Sonnet 5, and later models support extended thinking. Haiku 4.5 does not.
- Confirm
budget_tokensis at least 1024 and less thanmax_tokens. The SDK returns a validation error if these constraints are violated. - If you built a wrapper around the SDK, check that your wrapper is passing the
thinkingparameter as a plain dict, not a constructor call.
Real-world example: extended thinking in a math tutor
Here is a working production pattern for an AI math tutor that uses extended thinking to solve multi-step problems.
import anthropic
def solve_with_reasoning(problem: str, thinking_budget: int = 16000):
"""Solve a math problem with visible chain-of-thought reasoning."""
client = anthropic.Anthropic()
resp = client.messages.create(
model="claude-opus-4-8",
max_tokens=32000,
thinking={"type": "enabled", "budget_tokens": thinking_budget},
messages=[{
"role": "user",
"content": f"Solve step by step: {problem}"
}]
)
reasoning = ""
answer = ""
for block in resp.content:
if block.type == "thinking":
reasoning += block.thinking
elif block.type == "text":
answer += block.text
return {"reasoning": reasoning, "answer": answer}
result = solve_with_reasoning("If a train leaves NYC at 60mph and another leaves Chicago at 70mph...")
print("Chain of thought:\n", result["reasoning"][:500])
print("\nFinal answer:\n", result["answer"])Common mistakes with extended thinking
- Setting budget_tokens higher than max_tokens. The SDK rejects this immediately with a validation error, not an AttributeError.
- Using a model that does not support thinking. Sending the thinking parameter to Haiku or older Sonnet models returns a 400 error.
- Trying to stream thinking blocks the same way as text blocks. Thinking blocks arrive in a separate event type when streaming.
- Assuming thinking output is user-facing. Anthropic explicitly recommends showing thinking to developers for debugging only, not to end users by default.
Python AttributeError debugging checklist
- Print the actual type. Insert
print(type(obj))before the failing line — usually reveals the mismatch immediately. - Use dir().
print(dir(obj))lists all available attributes on the object. - Check version compatibility. Many AttributeErrors come from methods that were renamed or removed between library versions.
- Guard with hasattr().
if hasattr(obj, "method"): obj.method()— useful for cross-version code. - Use type hints + mypy. Static type checking catches most AttributeErrors before you run the code.
Common root causes across all AttributeError variants
- None return values. A function returned None when the caller expected an object.
- Version drift. Library API changed between versions.
- Variable overwrite. A local variable was reassigned with the wrong type (list → dict, str → int).
- Method vs attribute confusion. Calling a property with () or accessing a method without ().
- Missing initialization. Some frameworks require
init()before accessing certain attributes.
Modern Python tooling to prevent AttributeError
- Type hints + Optional[T]. Explicit null-handling in signatures.
- mypy or Pyright. Runs your codebase through a type checker before you run it.
- Ruff. Fast linter that catches many attribute-access issues.
- pydantic v2. Runtime validation with the same syntax as static types.
- pytest fixtures. Test with edge-case inputs to catch AttributeError paths early.
Official documentation
Common causes of this AttributeError
The AttributeError: ThinkingConfigEnabled object has no attribute budget_tokens almost always comes from a version mismatch or a wrong parameter name. Here are the three patterns I see most often in the Anthropic SDK on Python.
- Using an outdated SDK version. The
budget_tokensfield was renamed as the API evolved. Always pin your SDK to the latest stable version. Runpip install --upgrade anthropicand rerun your script. - Passing thinking config as a raw dict instead of the typed object. The Anthropic SDK expects
ThinkingConfigEnabledorThinkingConfigDisabledobjects, not plain dicts. Wrap your config properly using the correct type. - Confusing this with the beta API. The extended thinking feature had different parameter names during beta. If you copied code from an old tutorial, the field names may not match the current release.
Debugging checklist for Anthropic SDK errors
Before you rewrite your integration code, run through this checklist. It catches the most common causes of Anthropic SDK errors in about 5 minutes.
- Check your SDK version:
pip show anthropic. Compare with the latest release notes on the Anthropic docs. - Read the error trace top to bottom. The bottom line usually names the exact attribute or field that failed.
- Print the config object before passing it to the API:
print(repr(thinking_config))shows you exactly what type it is. - Check your API key and organization ID are set correctly in environment variables.
- Test with a minimal reproducer: strip the code down to the smallest example that reproduces the error, then add complexity back one piece at a time.
Most AttributeErrors on the Anthropic SDK resolve within the first two checks. When they do not, the reproducer step almost always finds it because you can inspect the object at each stage.
Quick step-by-step summary (click to expand)
- Upgrade to the latest Anthropic SDK. Run pip install –upgrade anthropic. The budget_tokens field was renamed as the extended thinking API evolved.
- Pass thinking config as a typed object. Import ThinkingConfigEnabled from anthropic.types and pass an instance rather than a raw dict.
- Verify SDK version matches your code. Run pip show anthropic and compare with the release notes to confirm the field names you use match this SDK version.
- Test with a minimal reproducer. Strip your code to the smallest call that triggers the error, then add complexity back one step at a time.
Frequently Asked Questions
Why does the SDK reject constructor-style ThinkingConfigEnabled?
The SDK’s TypedDict definition does not expose fields as class attributes. Constructor calls succeed but downstream code that reads .budget_tokens raises AttributeError. Passing a dict literal skips that failure path.
What is the minimum budget_tokens value?
1,024. Below that the SDK returns a validation error. Typical values in production are 8,000-32,000 depending on task complexity.
Does extended thinking increase token costs?
Yes. Thinking tokens are billed at the same rate as output tokens. Budget accordingly. A budget of 16,000 thinking tokens can add $0.20-$0.40 per Claude Opus request depending on the tier.
Which models support extended thinking in 2026?
Claude Opus 4.7 and 4.8, Claude Sonnet 5, and later. Haiku 4.5 does not currently support thinking. Check the Anthropic model matrix for the latest support list.
Should I show thinking to end users?
Anthropic recommends against showing thinking blocks to end users by default. Thinking output is meant for developer debugging and safety review. Only expose thinking when your product design specifically calls for chain-of-thought visibility.
