can1357/oh-my-pi · error · ConfigurationError

Anthropic thinking budget requires max_tokens greater than $

Error message

Anthropic thinking budget requires max_tokens greater than ${OUTPUT_FALLBACK_BUFFER}; got ${raisedMaxTokens}

What it means

AIError.ConfigurationError thrown by ensureMaxTokensForThinking in the Anthropic provider. Anthropic requires thinking budget_tokens to be strictly less than max_tokens; the library reserves OUTPUT_FALLBACK_BUFFER (4000) tokens for non-thinking output, so it raises max_tokens to budgetTokens + 4000 first. If even the raised max_tokens (after any provider/user cap) cannot exceed the buffer — i.e. clamped = raisedMaxTokens - 4000 <= 0 — no valid thinking budget exists and the request is rejected before hitting the API.

Source

Thrown at packages/ai/src/providers/anthropic.ts:3174

function ensureMaxTokensForThinking(params: MessageCreateParamsStreaming, maxAllowedTokens: number): void {
	const thinking = params.thinking;
	if (thinking?.type !== "enabled") return;

	const budgetTokens = thinking.budget_tokens ?? 0;
	if (budgetTokens <= 0) return;

	const currentMaxTokens = Math.min(params.max_tokens ?? maxAllowedTokens, maxAllowedTokens);
	const raisedMaxTokens = Math.min(
		Math.max(currentMaxTokens, budgetTokens + OUTPUT_FALLBACK_BUFFER),
		maxAllowedTokens,
	);
	params.max_tokens = raisedMaxTokens;

	if (budgetTokens + OUTPUT_FALLBACK_BUFFER <= raisedMaxTokens) return;

	const clampedBudget = raisedMaxTokens - OUTPUT_FALLBACK_BUFFER;
	if (clampedBudget <= 0) {
		throw new AIError.ConfigurationError(
			`Anthropic thinking budget requires max_tokens greater than ${OUTPUT_FALLBACK_BUFFER}; got ${raisedMaxTokens}`,
		);
	}
	thinking.budget_tokens = clampedBudget;
}

function applyCacheControlToLastBlock(blocks: ContentBlockParam[], cacheControl: AnthropicCacheControl): boolean {
	for (let index = blocks.length - 1; index >= 0; index--) {
		const block = blocks[index];
		// Anthropic rejects cache_control on generated reasoning and fallback
		// boundary blocks. Preserve the requested trailing boundary on every
		// ordinary content block, including tool use and tool results.
		if (block.type === "thinking" || block.type === "redacted_thinking" || block.type === "fallback") {
			continue;
		}
		if ("cache_control" in block && block.cache_control != null) return false;
		blocks[index] = { ...block, cache_control: cloneAnthropicCacheControl(cacheControl) };
		return true;

View on GitHub (pinned to 9690622007)

Solutions

  1. Raise max_tokens so it exceeds OUTPUT_FALLBACK_BUFFER (4000) — e.g. max_tokens >= budget_tokens + 4000
  2. Raise thinking.budget_tokens above 4000 (Anthropic's practical minimum is 1024, but this library needs budget + 4000 headroom within max_tokens)
  3. Check the model's max output limit; if the model caps max_tokens at <= 4000, use a model with a higher output limit or disable extended thinking
  4. Remove any explicit max_tokens cap in your request/options that forces raisedMaxTokens <= 4000

Example fix

// before
const params = { max_tokens: 3000, thinking: { type: "enabled", budget_tokens: 2000 } };
// after: leave headroom for output (budget + 4000 buffer)
const params = { max_tokens: 6000, thinking: { type: "enabled", budget_tokens: 2000 } };
Defensive patterns

Strategy: validation

Validate before calling

function assertThinkingFits(maxTokens: number, budgetTokens: number): void {
  const OUTPUT_FALLBACK_BUFFER = 4000;
  if (budgetTokens + OUTPUT_FALLBACK_BUFFER > maxTokens) {
    throw new Error(
      `max_tokens must exceed budget_tokens + ${OUTPUT_FALLBACK_BUFFER}; got max_tokens=${maxTokens}, budget=${budgetTokens}`,
    );
  }
}

Try / catch

try {
  const result = await session.prompt(model, paramsWithThinking);
} catch (err) {
  if (err instanceof AIError.ConfigurationError && err.message.includes("thinking budget")) {
    // fix config: raise max_tokens or lower/raise budget_tokens, then retry once
  }
  throw err;
}

Prevention

When it happens

Trigger: Sending a request with extended thinking enabled whose budget_tokens is <= OUTPUT_FALLBACK_BUFFER (4000) while the effective max_tokens after raising is <= 4000 — practically a thinking budget at or below 4000 tokens combined with a max_tokens cap that keeps raisedMaxTokens <= 4000, in ensureMaxTokensForThinking (packages/ai/src/providers/anthropic.ts:3165).

Common situations: Configuring thinking budget_tokens of 1024/2048 (small values copied from examples) with a low max_tokens; a model or deployment policy caps max_tokens at/below 4000; a model cap or KDL limits rule forces raisedMaxTokens below the buffer so clampedBudget <= 0.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/794b3c26c3385ed3. Report an issue: GitHub.