[BUG] 400 "output_config.effort 'xhigh' is not supported when thinking is disabled" on Opus 4.8 despite alwaysThinkingEnabled: true (VS Code, 2.1.205–2.1.207)
Bug description
On Claude Opus 4.8 with effortLevel: "xhigh", requests intermittently fail with:
API Error: 400 output_config.effort 'xhigh' is not supported when thinking is disabled on this model. Use effort 'high' or below, or enable thinking.
This happens despite alwaysThinkingEnabled: true in settings.json (key verified to exist against claude-code-settings.schema.json shipped with the extension). It looks like the client omits thinking: {type: "adaptive"} in some requests while still sending effort: "xhigh", which the API rejects.
Environment
- Claude Code: 2.1.205 → 2.1.207 (error reproduced across both)
- Entrypoint: VS Code extension (
claude-vscode), Windows 11 Home - Model: Claude Opus 4.8 (subscription)
settings.json:effortLevel: "xhigh",alwaysThinkingEnabled: true(both schema-valid)- Env:
CLAUDE_EFFORT=xhigh
Frequency / evidence
Counted from session transcripts (~/.claude/projects/*/*.jsonl), matching only synthetic API-error records ("isApiErrorMessage":true + the error text), main thread only:
- 13 error events total: 7 on 2026-07-09, 6 on 2026-07-11, across 7 different sessions
- All events have
isSidechain: false(main conversation loop); 0 events in subagent transcripts — subagents never hit this - 3 of the 13 records share an identical timestamp within one session (likely one event recorded three times, or instant retries)
Expected
With alwaysThinkingEnabled: true (or absent, per its schema description: "When absent or true, thinking is enabled automatically for supported models"), every request on Opus 4.8 with effort: xhigh should include thinking: {type: "adaptive"} and succeed.
Actual
Some main-loop requests run without thinking and get rejected with the 400 above. Behavior is intermittent within the same session and across sessions started with identical config.
Possibly related
- Changelog v2.1.203: "Fixed background sessions ignoring
effortLevelchanges in settings.json when forked through the daemon" — same class (effort/thinking config not propagated), shipped right before this started for me (first event 2026-07-09 on 2.1.205) - #65863 (
400 thinking options type cannot be disabled when reasoning_effort is set) - #68567 (
thinking.disabled.display: Extra inputs are not permittedon subagent spawns)
Workarounds found
- Switch to a model where thinking cannot be disabled (Fable 5): error is architecturally impossible there, confirmed gone after switching mid-session
- Or drop to
effortLevel: "high"on Opus 4.8 (error only fires onxhigh)
Showing cached comments. Read the full discussion on GitHub ↗
12 Comments
x-loading() : [~twitter] : [R: format - [Goals- based revenue]] => thinking done by x. High is suitable temperature enabled , Then a prod selection done from app to end base . High resolutions . [Re-rectify(..users,…tags)]
[Frequency_distribution = false , Context_Reselect = 'always true']
[events-main : 'fallback' , error : 'retrive' , trace_info : 'Backyard']
[Reasoning = high . [direction = x, x-enabled , x-transfer , x-files: ['off']]]
[Feedback = 'cage' , files = 'NP' , NA is applicable
]
Same 400 on the CLI (not VS Code) at 2.1.208, with a deterministic repro and what looks like a regression boundary at 2.1.207.
Up front: my failures surface differently from yours (last section), so this may be a sibling surface of the same root cause rather than the same events.
Environment — CC 2.1.208 (CLI, native install), Windows 11 Pro · Opus 4.8 (
claude-opus-4-8[1m]), subscription ·settings.json:effortLevel: "xhigh",alwaysThinkingEnablednot set at all (yours istrue) → the failure is independent of that key.Deterministic repro: the
WebSearchtool| time | effort | call | result |
|---|---|---|---|
| 02:10:03 |
xhigh| WebSearch |400 output_config.effort 'xhigh' is not supported…|| 02:28 | — |
/effort high| — || 02:29:30 |
high| WebSearch, identical query string | success |The cleanest evidence is one background subagent, one session, one effort setting: WebSearch 0/4, while WebFetch 4/4, Bash 12/12, Read 2/2, Grep 3/3, Write 2/2 all succeeded. The discriminator is the tool path, not the request in general.
(My
highcontrol is n=1 — read that row as "the one control passed", not "high never fails".)Likely a 2.1.207 regression, not a standing limitation
Scanned all 46,229 records across my project transcripts:
| period | CC version | Opus 4.8 WebSearch |
|---|---|---|
| through 2026-07-10 | ≤ 2.1.206 | 212 successes, 0 errors (74 transcripts) |
| from 2026-07-13 | ≥ 2.1.207 | 0 successes, 10 × this 400 |
Last success on 2.1.206, first failure on 2.1.207. My
effortLevel: xhighhas no modification across that boundary.Honest caveat: transcripts don't record the effort level, so I can't prove those 212 calls ran at
xhigh— only that the setting file wasn't touched. Treat it as strong circumstantial evidence for a regression, not proof.Model correlation: all 10 errors are
claude-opus-4-8. In the same sessions on the same version, subagents I spawned with an explicitmodel: sonnet(8/8) andmodel: haiku(1/1) had WebSearch succeed — consistent with the error text's "on this model".Your subagent conclusion is a measurement artifact
8 of my 10 failures are in subagents. Three reasons your filter cannot see them:
~/.claude/projects/<proj>/<session-id>/subagents/agent-*.jsonl. Your glob~/.claude/projects/*/*.jsonlis one level too shallow; they were never in the scan set.isSidechain— zero records in my entire 46,229-record corpus haveisSidechain: true. It cannot be used to identify subagents in current CC.isApiErrorMessage— WebSearch-path failures are not recorded as synthetic API-error records. The error text lands inside the WebSearch tool_result body, without even anis_errorflag. Your filter ("isApiErrorMessage":true+ error string) structurally cannot see a WebSearch failure — in the main loop or in a subagent.That third point is why I called this a sibling surface: your 13 events and my 10 are counted from different places. Same error string and same model, but I can't claim WebSearch is the trigger for your events — only for mine.
Possible mechanism
#68797 includes a v2.1.178 bundle analysis showing subagent requests hard-set
thinking: {type: "disabled"}while the parent'sdisplayleaks through. If the WebSearch server-tool sub-request is assembled along a similar path — thinking hard-disabled, effort inherited asxhigh— that produces exactly this 400. (Same family as the two you already linked.)Practical impact
Any agent whose core loop is web research degrades silently. It still runs and produces a report — with an entire source tier missing. One of my research runs logged it verbatim:
Nothing surfaced to the user.
Follow-up with a tighter repro than the one above — same agent, same session, same query string, 30 seconds apart, effort as the only variable.
Claude Code lets a skill override the session effort via its frontmatter (
effort: high). So I ran a probe inside a single background subagent (model inherited from the session = Opus 4.8,effortLevel: "xhigh"):| step | state |
WebSearch("Claude Code release notes")||---|---|---|
| 1 | before loading the skill — inherits session
xhigh|400 output_config.effort 'xhigh' is not supported when thinking is disabled on this model.|| 2 | load a skill whose frontmatter sets
effort: high| — || 3 | after loading it — effort now
high| success |No restart, no model change, no new session — the same agent, one tool call before and after the effort override. That is direct evidence that the WebSearch server-tool sub-request carries the session's current effort value while omitting
thinking, rather than the failure being intermittent or tied to session startup state.It also gives a workaround for anyone who wants to keep
xhighfor normal work: puteffort: highin the frontmatter of the skills/subagents that actually callWebSearch, and leave the globaleffortLevelalone. Verified working here — including inside background subagents, which is where 8 of my 10 failures were.Reply beneficial , Axiom : 'Intact' , Convo-co : [High , x - effort 'high'
, neural = 'perf'] , acrimonial , adequate , [Icon / flash][App
BI/Powerndex]
Index format [A:A , async ( Prod, J) : [Ofcourse , W : <Win-effort> ,
<Success-rate> <chance>]]
Main-Index : [dequeue() , [Coded m , M-self , [Vitest.j]
[Greyest=core-factor , Mature_parabolics , [Ensure , exponential zø]]
[Configure - G, model (index: format , mail , [iron - [Se ,
boot-loader[Trans:v ,Gay() , Liberal]]])] , [X-format :
[Rate-convey(monthly , trials)]
[Vputer , Vjeter , Tram-puter, [Arcquien , Nxv - [v-stance (Offneck :
[Allow 'exist' , without judgement])]]]
Take a form about work indexing , Times , work-ethics , Improve , Model
Humanization , Measure practics ,
Informal route-registery : <Root-pruning to main-gate , model=-fallbacks ,
[Ideas => virtual , auditory(input)]>
Context-lex-Lesional : [legional , leisurable , Re-durable , temp-text ,
walls , arrear-brigade , content[e-flash]]/
Fm , Self-[Morbidics, Morbidics : Dxi [Xc i : Ct[v . v-driver()]]]
Stem : [Iverbie : [verbate, time ]master-off : , sync(Chrononary(:-:))]
Tim-stutter , Apple - vB[vent-box]
Vento-[Kindle, / off-code : bash , pre-load(stash , LLMV) : V:sat , [IE :
<Rogue , Format>]]
]]]]
On Tue, 14 Jul 2026 at 10:10, TaeHwan Jung @.***> wrote:
Another datapoint from macOS - this is labelled
platform:windows, but it reproduces on Darwin too, and it is still live on 2.1.215.Environment: Claude Code 2.1.215 (CLI, native install), macOS (Darwin 24.6.0, x86_64) · Opus 4.8, subscription ·
~/.claude/settings.json:effortLevel: "xhigh",alwaysThinkingEnablednot set ·CLAUDE_EFFORT=xhigh. Hit live on aWebSearchcall today.Corroborating @taehwanis on the measurement artifact
Scanning my transcripts: 27 error records, and 25 of them have
isApiErrorMessage: null- only 2 aretrue. All 27 haveisSidechain: false. So theisApiErrorMessage: true+isSidechainfilter structurally under-counts this, now confirmed on a second machine and a second OS.Where my data differs: no clean regression boundary
With the settings file untouched throughout, Opus 4.8 WebSearch days alternate between fully failing and fully succeeding:
| date | WebSearch calls (model) | effort-400 records |
|---|---|---|
| 2026-07-09 | 14 × opus-4-8 | 2 |
| 2026-07-10 | 4 × sonnet-5 | 0 |
| 2026-07-13 | 6 × opus-4-8 | 0 |
| 2026-07-14 | 14 × opus-4-8 | 17 |
| 2026-07-15 | 1 × opus-4-8 | 1 |
| 2026-07-16 | 6 × opus-4-8 | 0 |
| 2026-07-17 | 8 × opus-4-8 | 0 |
| 2026-07-19 | 1 × opus-4-8 | 1 |
| 2026-07-20 | 3 × opus-4-8 | 7 |
(Error counts exceed call counts on some days - retries.)
2026-07-13, 07-16, and 07-17 are Opus 4.8 successes well past the 2.1.207 boundary, which fits the original report's "intermittent" framing better than a hard version regression.
Same caveat @taehwanis raised, and it cuts against my own rows: transcripts don't record effort, so I cannot prove those succeeding calls ran at
xhigh. A mid-session/effortchange or a skill witheffort:frontmatter would silently lower it - which is exactly the documented workaround. Treat the zero rows as not yet explained rather than as proof of intermittency.The sonnet-5 row on 07-10 is consistent with the model correlation already reported.
Practical impact
Seconding the silent-degradation point. The failure surfaces inside the tool result rather than as a client error, so a research run completes and reports normally with a whole source tier missing. I only found the 27 records because I went looking after noticing searches "not working" for about a week.
Correcting my own phrasing above, because it was ambiguous in a way that matters.
I wrote "
alwaysThinkingEnablednot set". That is accurate about the config files - the key is absent from~/.claude/settings.json, bothsettings.local.jsonfiles, my project settings, and~/.claude.json. But "not set" reads as "thinking is off", and it is not. Per the schema description, absent means enabled: "When absent or true, thinking is enabled automatically for supported models."/configconfirms it, showing Thinking mode: true.So on my machine thinking is ON by the client's own account, and the API still rejects the request with
...is not supported when thinking is disabled. That is the same contradiction @NormikRoma reported with an explicittrue, reached from the other direction (absent + default).Three surfaces disagree about one setting:
| surface | says |
|---|---|
|
/configUI | Thinking mode:true|| every settings file | key absent |
| API response | "thinking is disabled" |
Possibly relevant:
~/.claude.jsonon this machine containsthinkingMigrationComplete: true, alongsideunpinOpus48LaunchEffort: true. If a migration cleared/normalised the key and some downstream request-assembly path treats absent as disabled rather than applying the documented "absent means enabled" default, that yields exactly this 400.I have not verified that mechanism, only the three-way disagreement above. Flagging it as a hypothesis, not a finding.
If thinking mode is like absent, will absent-minded be the truth ,
therefore I can say , Local -
extension, in.form , nodes . Impair and recall ,
#logDhanamModhFunnel[Exvirst, Sitavorem]
Was there a predicament stating the thinking method was true ;
mod = [Z-com, I-c[Ct-vom[GPA |AA |Blade : sesh(Nerival)|]]] S:S{'export :
<prev:Pointer-Dorm(<derm-Friva : Vreet<Dhanam>)>}
,Beliebages : Preemnista : Nishta - [Netam , naram. thiram , noram
thannu , Naarm thaaki]
Hb-desk(),os-K[Ram, Species, Local(..slot(DDR%,
Cache-Forum(.base-Anthropy[Vaay-form , Chevi-kand, Ellam-Tholiyakkal ,
Vilpana-Korev, VoteDhanam Pirivu , Valya sankya ´´´´´´≤´ ´Thaladhorikkan m
, []mennam - p i l : [].
thallamk - dhvanum : <> novvam : pensil : []
Sorramab - fwenum : vuenum , nenam : Nakuam : anakkam , Merukkam ,
Thevruokkom , THorakk m : < > ´´´´´“‘´
Dhanam- Picham , _kota : Klivam , Makkyam , Mitta dhavanaum , menname
, ennam(>>discrete- single: [Multi [
Trdad: tederski , stuck : '' : thought - [Out by freedom - [But Knaved ,
caved,
Maened , ]] ]])]))) - [am,
repair - [H-cam, relations, near-headed : Agents , {
Narvy , Narvikulam<|VOYEM| VOYAGE | THRIVENI | SAAYKALL
Oflappy -[Dos-kirky :<Git.method(seat.am : [Set-em(+Best : [E: FLASH ://)])>
Joffttettd : <Setted : <<Tinkered: pair : >{
Form.segments {"Bit-clouds"}} *Habered:Methanine : F-e : <Formidable>
<Last <Drevsorm : <DROCKEL:RVM:MAEVM:MOEVEM:>>>
<Vowent : Vumia, Muayvakkal , Bhabar - Binbiya , BIniniya - Niviviyan g,
.Hot[Fix-Git-issue : Pr - Qquest : Ar , A-crit(.m-method, m1, m2 , m3 :
[M$ : {
Wish : Spring , I don't want to be seen ,
While Tinkering those .sectoring(Inker. , Ingress : pair , Protect
::Coupe : <VOOTEM , TEMFEE>
(Gov-cache : <Suiinap - []hekkmagire - ovkersk - [] Serk -
versh : <oversk-selguard<Doverks- [Berf-Sta , : Sel- mode : sensory -
[Op- load{factory , ophthal()}]]>>>
Ev-Sans : <Bovern-Teguor - [Sorver : drior : : [¯- : {Diemem , mem, foy,
soy , doy}]]>
)
[Year of act, sel.guard = 'gravity . nation. guard()']
Gravity : pod , Z1 : r , sim : <Satellite : lite-E : From , :
Adjugations>
Lettering : Dos - {Et-com , .dot-pile : frequental , E-fumdal , Defundal
: <Sort-Dental , [Set-am : drill(Et-k : 'Fry-Am- Frill(<bm- Cry : [
Baesrokom , sortram : fill , []
maeve : stromg , Fortatnc(Arctrc) : gill , []
Phre mpi : morragirr, [ ]
evkkom - sir , []
sorvemfir =>(0,9,8, 6 , 7 , 8 : [cloch :hr , froyem -nii, nin-vekka, buoyom
, cuovum ])])')] > }
)
Solve.stia(Statos : Maters: Es-risk : Ractual)
}])]
]
,X- Expert- Manual : <Use : 'Thinking m ,enable: 'usual like a 3- form
graduate, ! Dir-Coagulate(,Hot-Fixes - [X: farm , Deskinbound(Freighted:
Gill)]) , effort = '1' , relu. - Uli , Uli - a: calculator [Gtm : pi ,
favour - r - k : sins()]''>
Averg_Nansxi(Scam-Vi, faxs() ,sockerem : em-Term(<pv- vern(Sir, num : v,)))
Coverg_Transxi(-Sravnum , Kravki, krave-num , Sarv-Kyi - [Sockeram ,
Sort - rei , Veet- rm, [>Rover -I]])
Dexicanam : Covert-Correct : Frect-covi - Dover - Direct
{Crat:Fix-e:V-Tot(et . et , et - [ , _petty , chaos : <Road, sigil ,
Dhyanam , Komd , Menchal>]
Menchattt: Chattakam ? [''ollath] , ac : <after-care>
)}
}]]]
On Mon, 20 Jul 2026 at 14:18, Ostap Senyuk @.***> wrote:
(Posted by Opus 5)
Same error string on Opus 5, but this looks like a deterministic variant that's worth separating from the intermittent Opus 4.8 report — different trigger, and two concrete client-side causes.
Env: claude-code
2.1.219(CLI, macOS), modelclaude-opus-5.Repro (100%, not intermittent)
effortLevel: "xhigh"insettings.json(or/effort xhigh)/config→ "Thinking mode" → offAPI Error: 400 output_config.effort 'xhigh' is not supported when thinking is disabled on this model. Use effort 'high' or below, or enable thinking.Unlike the original report, this does not require
alwaysThinkingEnabledto be set at all. In my case the key is absent entirely — which per its own schema description means thinking is enabled:The disable comes from session-scoped
appState.thinkingEnabled, which the Tab hotkey flips (tengu_thinking_toggled_hotkey) and which nothing reconciles against settings until a new session. So/configandsettings.jsoncan both say thinking is on while the session sendsthinking: {type: "disabled"}.The 400 itself is correct API behavior
Per the Opus 5 migration doc bundled in the CLI:
That explains why this surfaces on Opus 5 specifically — 4.8 tolerated the combination. So the server is right; the bug is that the client can build that request, and then can't recover from the rejection.
Bug 1 — the effort resolver isn't thinking-aware
Thinking is sent as disabled straight from session state:
But the effort resolver clamps
xhighonly on model capability and org limits — never on thinking state:claude-opus-5's capability list containsxhigh_effort, soxhighis emitted next tothinking: {type:"disabled"}— an unconditionally invalid pair. Clamping effort tohighwhen thinking is disabled (or refusing to disable thinking abovehigh) would keep the request valid.Bug 2 — the existing retry can't match the new error text
There is already a safety net that latches effort as unsupported and retries without it (
tengu_effort_unsupported_retry, loggingrejected output_config.effort; latching unsupported and retrying without it). Its matcher:The Opus 5 message —
output_config.effort 'xhigh' is not supported when thinking is disabled on this model— matches neither branch, so the retry never fires and the raw 400 reaches the user. Widening this matcher would make the failure degrade gracefully even if Bug 1 stays.Also affects server-side tool sub-requests
Not just the main loop — a
WebSearchcall in the same session failed with the identical 400, returned as a tool error rather than a retry.Workaround
/config→ "Thinking mode" → on, or drop tohigh.Toggling
/fastdoes not help, which is a notable red herring: the fast-mode toggle never touchesthinkingEnabled, and fast mode is visually indistinguishable from thinking-off on Opus 5 because raw thinking tokens are never returned there (displaydefaults to"omitted"). I initially misdiagnosed my own case as fast-mode-related for exactly that reason.This bug is a scope leak: a session-wide setting (effort) propagates into an internal sub-request that has different constraints (thinking disabled for latency).
The CLI's WebSearch tool does not run in main conversation. It fires a separate API request with a fixed system prompt and the server-side web_search tool forced via tool_choice. In 2.1.220 that request is built as:
thinkingConfig: { type: "disabled" }, // **hardcoded**
...
model: p, // = your mainLoopModel (claude-opus-5)
effortValue: Sb(t) // = your session effort = "xhigh"
Sb()readsgetAppState().effortValueand forwards it unconditionally.So the request says "effort xhigh, thinking off" - exactly the combination the API rejects.
Loop affects : servers , [if not like close -matched , The effort affect.
readact : <
H.type = disable , config.return [mini_state , chat : case = 'x-high']
Type.rebuild : action.server-status = 404 : [
Return status.build = server-configs.//rename 'x' , redact [counter:c]]>]
output = effort.parameters{404,'rebuild', update_name , thinking_mode =
.NET/main()}
t&t.effort[include , efforts = config , action =
'extra'].update('silver-stream' , new(session) : 'x-high-thinking mode' :
'enabled')
On Sat, 25 Jul 2026 at 10:36, Bas Nijholt @.***> wrote:
If cloud server.session : update , is being root-timed and hit the same
terminal via hardcoded : [
if mainLoopModel = cloud.server | Action'pinpoint' , Main-loop = [
roundabout , app.get(status ? X = App.readystate)]
info_login : mismatch : <New_selctions : form-guide , seperations>
Cli-login : <Main-search>[match : terminal , applications = encoding]
]
On Mon, 3 Aug 2026 at 05:21, Tim Cosgrove @.***> wrote: