आपने Claude API में इस्तेमाल होने वाला मॉडल नए वर्ज़न पर बदला, और अब नीचे वाली एरर आने लगी। या रिस्पॉन्स का टेक्स्ट ख़ाली लौटने लगा। वजह आम तौर पर एक ही होती है: रिस्पॉन्स का पहला कंटेंट ब्लॉक (content[0]) अब टेक्स्ट नहीं, बल्कि सोचने की प्रक्रिया का ब्लॉक (thinking ब्लॉक) बन गया है।
AttributeError: 'ThinkingBlock' object has no attribute 'text'
अगर आप Python SDK में response.content[0].text पढ़ते हैं, तो यही एरर आती है। JavaScript में वही कोड undefined लौटाता है, इसलिए एरर आने के बजाय ख़ाली स्ट्रिंग आपके ऐप में आगे बढ़ जाती है। मुश्किल बात यह है: सरल इनपुट पर पहला ब्लॉक अब भी टेक्स्ट रहता है, इसलिए हल्के इनपुट वाले टेस्ट पास हो जाते हैं।
समस्या तीन लाइनों में
क्या होता है
पहला ब्लॉक अब टेक्स्ट नहीं रहता
ज़्यादातर भारी इनपुट पर रिस्पॉन्स में सबसे पहले thinking ब्लॉक आता है (कभी-कभी हल्के इनपुट पर भी)। content[0].text टूट जाता है।
वजह
बिना कहे सोचता है
Claude 5 और उसके बाद के मॉडल thinking सेट न करने पर भी ज़रूरत पड़ने पर सोचते हैं। Claude 4 मॉडल तब तक नहीं सोचते जब तक आप इसे सेट न करें।
समाधान
ब्लॉक को टाइप से खोजें
पहले ब्लॉक को मानकर न चलें। वे ब्लॉक इकट्ठा करें जिनका type "text" है, और stop_reason भी जाँचें।
1. यह कब होता है
आम मामला ऐसा माइग्रेशन है जिसमें आप सिर्फ़ मॉडल का नाम बदलते हैं। उदाहरण के लिए, आप सिर्फ़ model की वैल्यू बदलकर Claude Sonnet 4.6 से Claude Sonnet 5.5 पर जाते हैं। यह मानकर कि रिस्पॉन्स का आकार वही है, आप बाक़ी कोड को नहीं छूते। तब नीचे दी गई बातें होती हैं (तीसरी बात सही तरह से लिखे कोड में भी होती है)।
| पढ़ने का तरीक़ा | क्या होता है |
|---|---|
Python SDK में content[0].text | AttributeError: 'ThinkingBlock' object has no attribute 'text' पर रुक जाता है |
JavaScript में content[0].text | कोई एरर नहीं; वैल्यू undefined हो जाती है, और स्क्रीन या स्टोरेज में ख़ाली टेक्स्ट पहुँच जाता है |
| टेक्स्ट ब्लॉक खोजकर पढ़ना | अगर मॉडल बहुत सोचता है और max_tokens तक पहुँच जाता है, तो हो सकता है कोई टेक्स्ट ब्लॉक हो ही नहीं |
तीसरी बात सही तरह से लिखे कोड में भी होती है। thinking के टोकन भी max_tokens में गिने जाते हैं, इसलिए अगर लिमिट छोटी है, तो मॉडल के कोई टेक्स्ट लिखने से पहले ही रिस्पॉन्स कट जाता है।
2. वजह: Claude 5 और उसके बाद के मॉडल बिना कहे सोचते हैं
Anthropic के डॉक्यूमेंट "Thinking" में हर मॉडल के लिए बताया गया है कि रिक्वेस्ट में thinking न होने पर क्या होता है। विभाजन रेखा Claude 5 है।
| मॉडल | thinking के बिना | thinking का कंटेंट |
|---|---|---|
| Claude 5 और उसके बाद (Opus 5.5, Sonnet 5.5, Haiku 5.5, Fable 5.1 आदि) | सोचता है (adaptive thinking) | डिफ़ॉल्ट रूप से ख़ाली (display: "omitted") |
| Opus 4.8, Opus 4.7 | नहीं सोचता | सिर्फ़ thinking: {type: "adaptive"} सेट करने पर सोचता है; कंटेंट डिफ़ॉल्ट रूप से ख़ाली ("omitted") |
| Opus 4.6, Sonnet 4.6 | नहीं सोचता | सिर्फ़ thinking: {type: "adaptive"} सेट करने पर सोचता है; डिफ़ॉल्ट रूप से सारांश लौटाता है ("summarized") |
स्रोत: Anthropic के "Thinking" की मॉडल-वार तालिका और display का विवरण (1 नवंबर 2026 को जाँचा गया)। Opus 4.5, Sonnet 4.5 और Haiku 4.5 {type: "adaptive"} स्वीकार नहीं करते; इनसे thinking करवाने के लिए {type: "enabled"} के साथ budget_tokens इस्तेमाल करें।
सोचना है या नहीं, यह मॉडल हर इनपुट के लिए ख़ुद तय करता है। "Steering thinking" डॉक्यूमेंट बताता है कि सरल तथ्यात्मक सवालों पर मॉडल thinking ब्लॉक के बिना जवाब दे सकता है। फिर वह सावधान करता है कि अपने ऐप्लिकेशन का लॉजिक इस धारणा पर न बनाएँ कि हर रिस्पॉन्स thinking ब्लॉक से शुरू होगा। यानी पहला ब्लॉक कभी टेक्स्ट होता है और कभी thinking। जो कोड इनमें से किसी एक को मानकर चलता है, वह कहीं न कहीं टूटेगा।
रिस्पॉन्स का कंटेंट नीचे दिखाए क्रम में आता है। thinking का कंटेंट डिफ़ॉल्ट रूप से ख़ाली होता है, लेकिन ब्लॉक अपने आप में फिर भी लौटता है।
हल्का इनपुट (उदा., जापान की राजधानी?)
[0]textटोक्योभारी इनपुट (उदा., शर्तें पूरी करने वाली सभी संख्याएँ खोजें)
[0]thinkingख़ाली, सिर्फ़ सिग्नेचर[1]textजवाबभारी इनपुट जो max_tokens तक पहुँच जाए
[0]thinkingख़ाली, सिर्फ़ सिग्नेचरtext नहींstop_reason: "max_tokens"3. टेस्ट में क्या मिला
मैंने 1 नवंबर 2026 को अपने एनवायरनमेंट में Python SDK (anthropic 1.14.0) से इसे टेस्ट किया। चार मॉडलों को एक हल्का और एक भारी इनपुट एक-एक बार भेजा, thinking के बिना भी और {type: "adaptive"} के साथ भी। max_tokens को 8000 रखा। हल्का इनपुट एक सरल तथ्यात्मक सवाल था, जिसमें एक शब्द में जापान की राजधानी पूछी गई थी (सवाल जापानी में पूछा गया); भारी इनपुट एक सवाल था जिसमें पाँच शर्तें पूरी करने वाले सभी चार अंकों के पूर्णांक खोजने थे।
| मॉडल | thinking सेटिंग | content (हल्का इनपुट) | content (भारी इनपुट) |
|---|---|---|---|
| Sonnet 4.6 | सेट नहीं | text | text |
| Sonnet 4.6 | adaptive | text | सिर्फ़ thinking (लिमिट पर पहुँचा) |
| Haiku 5.5 | सेट नहीं | text | सिर्फ़ thinking (लिमिट पर पहुँचा) |
| Haiku 5.5 | adaptive | text | सिर्फ़ thinking (लिमिट पर पहुँचा) |
| Sonnet 5.5 | सेट नहीं | text | thinking → text |
| Sonnet 5.5 | adaptive | text | thinking → text |
| Opus 5.5 | सेट नहीं | text | thinking → text |
| Opus 5.5 | adaptive | thinking → text | thinking → text |
लाल रंग वे संयोजन दिखाता है जिनमें content[0].text ने AttributeError: 'ThinkingBlock' object has no attribute 'text' दी। हर नतीजा एक ही रन का है; एक ही इनपुट पर भी मॉडल सोचेगा या नहीं, यह रन-दर-रन बदल सकता है।
तीन बातें सामने आईं।
पहली, Claude 5 और उसके बाद के मॉडलों ने thinking के बिना भी भारी इनपुट पर सोचा। Sonnet 4.6 में इसे छोड़ देने पर पहला ब्लॉक टेक्स्ट ही रहा। इससे वही पुष्ट होता है जो डॉक्यूमेंट कहता है: सिर्फ़ मॉडल का नाम बदलने से रिस्पॉन्स का आकार बदल जाता है।
दूसरी, हल्के इनपुट पर लगभग हर संयोजन में पहला ब्लॉक टेक्स्ट था। अगर आपके टेस्ट सिर्फ़ हल्के इनपुट इस्तेमाल करते हैं, तो आपको यह समस्या नहीं मिलेगी। दूसरी ओर, adaptive के साथ Opus 5.5 ने हल्के इनपुट पर भी सोचा। Claude 5 और उसके बाद thinking छोड़ना और adaptive सेट करना एक ही कॉन्फ़िगरेशन है, इसलिए यह अंतर संभवतः रन-दर-रन का उतार-चढ़ाव है। आप यह नहीं कह सकते कि "हल्के इनपुट पर thinking नहीं होती।"
तीसरी, लिमिट पर पहुँचने पर कोई टेक्स्ट लौटा ही नहीं। भारी इनपुट पर Haiku 5.5 ने thinking के बिना और adaptive के साथ, दोनों बार सभी 8000 टोकन सोचने में ख़र्च कर दिए और कोई टेक्स्ट ब्लॉक नहीं लौटाया। adaptive के साथ Sonnet 4.6 भी लिमिट पर पहुँचा। Claude 5 और उसके बाद thinking का कंटेंट भी डिफ़ॉल्ट रूप से ख़ाली होता है, इसलिए यूज़र को कुछ नहीं दिखता, फिर भी आउटपुट टोकन का भुगतान करना पड़ता है।
4. इसे कैसे ठीक करें
समाधान यह है कि पहले कौन-सा ब्लॉक आएगा, यह मानना बंद करें और वे ब्लॉक इकट्ठा करें जिनका प्रकार टेक्स्ट है (type "text" है)। साथ ही stop_reason भी जाँचें, ताकि लिमिट पर कटे रिस्पॉन्स को सामान्य जवाब न मान लें।
Python
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=16000,
messages=[{"role": "user", "content": prompt}],
)
# पहले ब्लॉक को मानकर न चलें: सिर्फ़ टेक्स्ट ब्लॉक इकट्ठा करें
text = "".join(b.text for b in response.content if b.type == "text")
if response.stop_reason == "max_tokens":
# लिमिट पर कट गया। text ख़ाली हो सकता है
raise RuntimeError("max_tokens तक पहुँच गया। लिमिट बढ़ाएँ या thinking घटाएँ")
if response.stop_reason == "end_turn" and not text:
# टूल इस्तेमाल वाले फ़्लो में stop_reason "tool_use" होता है और ख़ाली text सामान्य है
raise RuntimeError("कोई टेक्स्ट ब्लॉक नहीं")
TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-sonnet-5-5",
max_tokens: 16000,
messages: [{ role: "user", content: prompt }],
});
// text पढ़ने से पहले टाइप से छाँटें
const text = response.content
.filter((b): b is Anthropic.TextBlock => b.type === "text")
.map((b) => b.text)
.join("");
if (response.stop_reason === "max_tokens") {
throw new Error("max_tokens तक पहुँच गया। लिमिट बढ़ाएँ या thinking घटाएँ");
}
// टूल इस्तेमाल वाले फ़्लो में stop_reason "tool_use" होता है और ख़ाली text सामान्य है
if (response.stop_reason === "end_turn" && text === "") {
throw new Error("कोई टेक्स्ट ब्लॉक नहीं");
}
TypeScript SDK में content के एलिमेंट टेक्स्ट, thinking और टूल इस्तेमाल जैसे टाइप का यूनियन होते हैं। सीधे content[0].text लिखने पर आम तौर पर टाइप चेक में ही एरर आनी चाहिए। लेकिन अगर आप as से टाइप ज़बरदस्ती तय कर देते हैं, तो यह ग़लती छूट जाती है।
max_tokens को thinking समेत तय करें
"Steering thinking" डॉक्यूमेंट बताता है कि max_tokens thinking और जवाब के टेक्स्ट की संयुक्त लिमिट है। वह यह भी बताता है कि यह मानकर चुनी गई लिमिट कि मॉडल नहीं सोचेगा, कठिन इनपुट के लिए अक्सर बहुत छोटी होती है। जब आपको stop_reason: "max_tokens" मिले, तो दो समाधान हैं।
ऊपर के उदाहरणों में 16000 एक मोटा अनुमान है। मेरे टेस्ट में कभी-कभी 8000 भी पूरा का पूरा thinking में ख़र्च हो गया। प्रोडक्शन के लिए भारी इनपुट चलाएँ और रिस्पॉन्स में usage.output_tokens_details.thinking_tokens (thinking में ख़र्च हुए टोकन की संख्या) देखकर वैल्यू तय करें।
- लिमिट बढ़ाएँ: जब कटे हुए इनपुट पर thinking से जवाब की गुणवत्ता बेहतर होती हो
- प्रयास (effort) घटाएँ: जब मॉडल बस ज़रूरत से ज़्यादा सोच रहा हो और जवाब की गुणवत्ता न बदलती हो (effort को
output_config.effortसे सेट करें)
बातचीत जारी रखते समय thinking ब्लॉक भी वापस भेजें
जब आप बातचीत के इतिहास में रिस्पॉन्स जोड़ें, तो सिर्फ़ टेक्स्ट न निकालें; content को जैसा है वैसा वापस भेजें। ख़ासकर टूल इस्तेमाल वाले फ़्लो में thinking ब्लॉक में टूल कॉल के पीछे का तर्क होता है। डॉक्यूमेंट कहता है कि मिले हुए ब्लॉक बिना बदलाव के लौटाएँ, और बदले हुए ब्लॉक 400 एरर के साथ अस्वीकार हो जाते हैं। सबसे सुरक्षित यह है कि दिखाने वाला टेक्स्ट और इतिहास में वापस भेजा जाने वाला content अलग-अलग रखें।
5. क्या thinking बंद कर देना काफ़ी है?
यह सोचना स्वाभाविक है कि "अगर thinking आड़े आ रही है, तो उसे बंद कर दो," लेकिन यह हो पाएगा या नहीं, यह मॉडल पर निर्भर करता है। thinking: {type: "disabled"} के साथ ऐसा होता है।
| मॉडल | {type: "disabled"} |
|---|---|
| Opus 5.5, Fable 5.1, Fable 5 | 400 एरर (बंद नहीं कर सकते) |
| Sonnet 5.5 | 400 एरर (इसके बजाय, effort high या उससे कम होने पर {type: "between_tools"} शुरुआती thinking छोड़ देता है) |
| Haiku 5.5, Opus 5 | बंद कर सकते हैं (सिर्फ़ तब जब effort high या उससे कम हो; xhigh और max पर 400 एरर) |
| Sonnet 5 | बंद कर सकते हैं |
स्रोत: Anthropic का "Thinking" (1 नवंबर 2026 को जाँचा गया)। कोई मॉडल इसे स्वीकार करता है या नहीं, यह Models API में capabilities.thinking.types.disabled.supported से भी जाँच सकते हैं। डिफ़ॉल्ट effort Opus 5.5 और Haiku 5.5 के लिए medium और ज़्यादातर दूसरे मॉडलों के लिए high है, इसलिए डिफ़ॉल्ट सेटिंग पर "high या उससे कम" की शर्त पूरी होती है।
जिन मॉडलों में इसे बंद किया जा सकता है, उनमें भी ऐसा करने से कठिन इनपुट पर जवाब की गुणवत्ता घट सकती है। और हर बार मॉडल बदलने पर वही समस्या लौट आती है। असली समाधान ऐसा कोड है जो किसी भी क्रम में आए रिस्पॉन्स को पढ़ सके। अगर आप thinking घटाना चाहते हैं, तो पहले effort घटाएँ। Anthropic के डॉक्यूमेंट के अनुसार, सिस्टम प्रॉम्प्ट में Sonnet 5.5 से कम सोचने को कहने से thinking भरोसेमंद ढंग से कम नहीं होती, और Haiku 5.5 सीधे जवाब देने को कहने पर भी सोचता रहा (Anthropic के टेस्ट में)। दोनों के लिए effort से एडजस्ट करें।
6. टेस्टिंग में इसे कैसे न चूकें
यह समस्या हल्के इनपुट वाले टेस्ट से बच निकलती है। मॉडल बदलते समय नीचे दिए क्रम में जाँचने से इसे चूकना मुश्किल हो जाता है।
- अपने कोड में
content[0]खोजें:content[0],content[-1]और.content[0].textजैसी हर जगह की सूची बनाएँ जो पोज़िशन से पढ़ती है, सिर्फ़ प्रोडक्शन कोड में नहीं, बल्कि टेस्ट और लॉगिंग में भी - टेस्ट में भारी इनपुट जोड़ें: प्रोडक्शन के सबसे लंबे इनपुट और सबसे कठिन काम टेस्ट इनपुट में शामिल करें (सिर्फ़ हल्के इनपुट से पहला ब्लॉक टेक्स्ट ही रहता है और गड़बड़ी छिपी रहती है)
- thinking ब्लॉक से शुरू होने वाले नक़ली रिस्पॉन्स डालें: API को कॉल न करने वाले यूनिट टेस्ट में
[thinking, text]वाला रिस्पॉन्स औरstop_reason"max_tokens"वाला सिर्फ़-thinkingरिस्पॉन्स तैयार करें, ताकि मॉडल सोचे या न सोचे, आप टेस्ट कर सकें - धीरे-धीरे रोलआउट करें: सब कुछ एक साथ न बदलें; पहले कुछ वर्कलोड नए मॉडल पर ले जाएँ, ख़ाली टेक्स्ट और एक्सेप्शन की गिनती देखें, फिर दायरा बढ़ाएँ
⚠️ जब कई सर्विस या टीमें एक साथ मॉडल बदलें, तो माइग्रेशन रिक्वेस्ट में एक लाइन जोड़ दें: "रिस्पॉन्स का पहला ब्लॉक हमेशा टेक्स्ट नहीं होता। उसे टाइप से खोजें।" यह बदलाव साधारण नाम-बदलाव जैसा दिखता है, और अगर आप हर टीम के ख़ुद ध्यान देने का इंतज़ार करेंगे, तो हल्के इनपुट वाले टेस्ट पास कर चुका कोड प्रोडक्शन में टूट जाएगा।
मॉडल बदलते समय जाँचने वाली बात सिर्फ़ यही नहीं है। पिछली पीढ़ियों से माइग्रेट करते समय क्या बदला, इसके लिए "Claude Opus 4.7 माइग्रेशन गाइड" और "Claude Fable 5.1 के 3 ब्रेकिंग चेंज और माइग्रेशन का तरीका" देखें। API में effort के बारे में Anthropic के "Effort" डॉक्यूमेंट में बताया गया है, और Claude Code में effort चुनने के बारे में "Claude Code की प्रयास (effort) सेटिंग" में।
सारांश
AttributeError: 'ThinkingBlock' object has no attribute 'text'तब आती है जब रिस्पॉन्स का पहला ब्लॉक thinking ब्लॉक हो और आपcontent[0].textसे टेक्स्ट पढ़ने की कोशिश करें- Claude 5 और उसके बाद के मॉडल
thinkingके बिना भी ज़रूरत पड़ने पर सोचते हैं, इसलिए Claude 4 मॉडल से सिर्फ़ मॉडल का नाम बदलने पर रिस्पॉन्स का आकार बदल जाता है - हल्के इनपुट पर पहला ब्लॉक आम तौर पर टेक्स्ट ही रहता है, इसलिए हल्के टेस्ट पास हो जाते हैं
- समाधान है वे ब्लॉक इकट्ठा करना जिनका
type"text"है, और यह जाँचना किstop_reason"max_tokens"है या नहीं - कुछ मॉडलों में thinking बंद नहीं हो सकती, इसलिए असली समाधान उसे बंद करना नहीं, बल्कि ऐसा कोड लिखना है जो किसी भी क्रम में रिस्पॉन्स पढ़ सके
अक्सर पूछे जाने वाले सवाल
प्र. मैंने thinking कभी सेट ही नहीं की। फिर thinking ब्लॉक क्यों मिलता है?
उ. Claude 5 और उसके बाद के मॉडलों में thinking के बिना भी adaptive thinking चालू रहती है, और जिन इनपुट पर मॉडल ज़रूरत समझता है, उन पर सोचता है। thinking का कंटेंट डिफ़ॉल्ट रूप से ख़ाली होता है, लेकिन ब्लॉक अपने आप में रिस्पॉन्स में शामिल रहता है। Claude Opus 4.8 और Sonnet 4.6 जैसे Claude 4 मॉडल तब तक नहीं सोचते जब तक आप इसे सेट न करें।
प्र. ऐसा रिस्पॉन्स क्यों मिलता है जिसमें कोई टेक्स्ट ब्लॉक ही नहीं?
उ. thinking के टोकन max_tokens में गिने जाते हैं, और मॉडल के कोई टेक्स्ट लिखने से पहले ही लिमिट पूरी हो गई। stop_reason "max_tokens" होना चाहिए। लिमिट बढ़ाएँ, या thinking घटाने के लिए effort कम करें।
प्र. अगर मुझे thinking का कंटेंट पढ़ना हो तो?
उ. thinking का सारांश पाने के लिए thinking: {type: "adaptive", display: "summarized"} सेट करें। Claude 5 और उसके बाद डिफ़ॉल्ट "omitted" है (कंटेंट ख़ाली रहता है और सिर्फ़ सिग्नेचर शामिल होता है)। दोनों ही मामलों में आपसे thinking के सभी टोकन का शुल्क लिया जाता है।
अपडेट लॉग
- 1 नवंबर 2026पहला संस्करण। Anthropic के "Thinking" और "Steering thinking" डॉक्यूमेंट की समीक्षा करके और अपने एनवायरनमेंट में चार मॉडलों के रिस्पॉन्स का क्रम टेस्ट करके लिखा गया।
स्रोत
- Anthropic: Thinking, Steering thinking