browser-use/browser-use · error · ValueError

{self.model} only supports adaptive thinking. Omit thinking

Error message

{self.model} only supports adaptive thinking. Omit thinking or use adaptive display options such as {"type": "adaptive", "display": "summarized"}.

What it means

Raised by ChatAnthropic._validate_thinking_config when the model is an adaptive-thinking-only model (per _is_adaptive_thinking_only_model, e.g. claude-fable-5 / claude-mythos-5 families) but the thinking dict uses the legacy extended-thinking API: type 'enabled'/'disabled' or a budget_tokens key. Those models accept only the adaptive form (or omitting thinking entirely), so the old config shape is rejected at construction/validation time.

Source

Thrown at browser_use/llm/anthropic/chat.py:110

	def _is_adaptive_thinking_only_model(self) -> bool:
		model = self.name.lower()
		return 'claude-fable-5' in model or 'claude-mythos-5' in model

	def _requires_auto_tool_choice(self) -> bool:
		model = self.name.lower()
		if 'claude-fable-5' in model or 'claude-mythos-5' in model:
			return True
		if self.thinking is None:
			return False
		return self.thinking.get('type') != 'disabled'

	def _validate_thinking_config(self) -> None:
		if not self.thinking or not self._is_adaptive_thinking_only_model():
			return

		thinking_type = self.thinking.get('type')
		if thinking_type in {'enabled', 'disabled'} or 'budget_tokens' in self.thinking:
			raise ValueError(
				f'{self.model} only supports adaptive thinking. Omit thinking or use adaptive display options such as '
				'{"type": "adaptive", "display": "summarized"}.'
			)

	def _get_betas_for_invoke(self) -> list[str] | None:
		betas = self.betas

		if self.fallbacks is None:
			return betas

		betas = list(betas or [])
		if not any(beta.startswith('server-side-fallback-') for beta in betas):
			betas.append('server-side-fallback-2026-06-01')
		return betas

	def _get_extra_body_for_invoke(self) -> dict[str, Any] | None:
		extra_body: dict[str, Any] = {}

View on GitHub (pinned to 6c73fced2f)

Solutions

  1. Omit the thinking parameter entirely for these models
  2. Or use the adaptive form: thinking={'type': 'adaptive', 'display': 'summarized'}
  3. Keep per-model configs instead of one shared thinking dict across model generations

Example fix

# before
llm = ChatAnthropic(model='claude-fable-5-sonnet',
                    thinking={'type': 'enabled', 'budget_tokens': 4096})

# after
llm = ChatAnthropic(model='claude-fable-5-sonnet',
                    thinking={'type': 'adaptive', 'display': 'summarized'})
Defensive patterns

Strategy: validation

Validate before calling

ADAPTIVE_ONLY = ('claude-fable-5', 'claude-mythos-5')

def validate_thinking(model: str, thinking: dict | None) -> None:
    if thinking and any(m in model for m in ADAPTIVE_ONLY):
        assert thinking.get('type') not in ('enabled', 'disabled') and 'budget_tokens' not in thinking, \
            'use {"type": "adaptive", ...} or omit thinking for this model'

Type guard

def is_adaptive_only_model(model: str) -> bool:
    return 'claude-fable-5' in model or 'claude-mythos-5' in model

Try / catch

try:
    llm = ChatAnthropic(model=model, thinking=thinking_cfg)
except ValueError as e:
    if 'adaptive thinking' in str(e):
        llm = ChatAnthropic(model=model)  # retry without thinking
    else:
        raise

Prevention

When it happens

Trigger: ChatAnthropic(model='claude-fable-5-...', thinking={'type': 'enabled', 'budget_tokens': 4096}); reusing a config written for claude-sonnet/opus extended thinking on a newer adaptive-only model.

Common situations: Upgrading to a new Claude model generation while keeping the old thinking payload; copying sample code that sets budget_tokens; enabling thinking unconditionally across a fleet of mixed models.

Related errors


AI-assisted analysis of browser-use/browser-use@6c73fced2f (2026-08-14). Data as JSON: /api/errors/9632a266b98e7c2f. Report an issue: GitHub.