openclaw - 💡(How to fix) Fix max thinking level rejected for Claude Opus 4.8 via custom anthropic-messages provider despite config + backend support

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

When Claude Opus 4.8 (and the Opus 4.7 / Sonnet 4.6 adaptive-thinking family) is served through a custom provider configured with api: "anthropic-messages", the max reasoning effort level is rejected by the gateway with:

Thinking level "max" is not supported for <provider>/claude-opus-4-8[1m].
Use one of: off, minimal, low, medium, high, xhigh.

This happens even when the model entry explicitly declares max in compat.supportedReasoningEfforts, and even though the backend transport mapping already supports the max effort level. The level is silently dropped while building the allowed thinking profile, so it never reaches validation as a permitted value.

This appears related to #84349 (custom anthropic-messages providers missing Claude thinking profiles), but is a distinct, independently reproducible defect in the profile-builder: there is a wiring path for xhigh but no equivalent path for max, and the model compat.supportedReasoningEfforts array is not consulted for max at all.

Root Cause

The thinking-profile builder (resolveThinkingProfile, bundled thinking-*.js) constructs the allowed level set roughly as:

const profile = binaryDecision === true
  ? buildBinaryThinkingProfile(defaultLevel)
  : buildBaseThinkingProfile(defaultLevel); // [off, minimal, low, medium, high]

if (binaryDecision !== true && catalogSupportsXHigh(context.compat))
  appendProfileLevel(profile, "xhigh");

// (provider-hook xhigh path) …
return profile;

Two concrete gaps:

  1. No max append path. There is catalogSupportsXHigh(compat) (which scans compat.supportedReasoningEfforts for xhigh) and a corresponding appendProfileLevel(profile, "xhigh"). There is no catalogSupportsMax equivalent and no appendProfileLevel(profile, "max"). As a result, max can never be added to the base profile via catalog config.

  2. compat.supportedReasoningEfforts is not consulted for max. Declaring ["low","medium","high","xhigh","max"] in the model config has no effect for max, because only the hard-coded xhigh check reads that array. So the documented-looking config knob is effectively a no-op for max.

Supporting evidence that max is otherwise fully supported in the system:

  • THINKING_LEVEL_RANKS defines max: 70 (above xhigh: 60), so it is a first-class level for ordering.
  • The Anthropic transport mapping already handles it: case "max": return "max"; in mapThinkingLevelToEffort (i.e. max is passed through as a distinct effort, not clamped down to xhigh).
  • EXTENDED_THINKING_LEVELS includes "max".

So the only missing piece is wiring max from catalog config into the allowed profile for anthropic-messages providers.

Code Example

Thinking level "max" is not supported for <provider>/claude-opus-4-8[1m].
Use one of: off, minimal, low, medium, high, xhigh.

---

{
  "id": "claude-opus-4-8[1m]",
  "name": "Claude Opus 4.8 1M",
  "reasoning": true,
  "contextWindow": 1000000,
  "maxTokens": 64000,
  "compat": {
    "supportedReasoningEfforts": ["low", "medium", "high", "xhigh", "max"]
  }
}

---

const profile = binaryDecision === true
  ? buildBinaryThinkingProfile(defaultLevel)
  : buildBaseThinkingProfile(defaultLevel); // [off, minimal, low, medium, high]

if (binaryDecision !== true && catalogSupportsXHigh(context.compat))
  appendProfileLevel(profile, "xhigh");

// (provider-hook xhigh path) …
return profile;

---

// 1) Add a catalog check symmetric to catalogSupportsXHigh:
function catalogSupportsMax(compat) {
  const efforts = compat?.supportedReasoningEfforts;
  return Array.isArray(efforts) && efforts.some((e) => normalizeThinkLevel(e) === "max");
}

// 2) Append it when the catalog (or provider policy) allows it:
if (binaryDecision !== true && catalogSupportsMax(context.compat))
  appendProfileLevel(profile, "max");
RAW_BUFFERClick to expand / collapse

Summary

When Claude Opus 4.8 (and the Opus 4.7 / Sonnet 4.6 adaptive-thinking family) is served through a custom provider configured with api: "anthropic-messages", the max reasoning effort level is rejected by the gateway with:

Thinking level "max" is not supported for <provider>/claude-opus-4-8[1m].
Use one of: off, minimal, low, medium, high, xhigh.

This happens even when the model entry explicitly declares max in compat.supportedReasoningEfforts, and even though the backend transport mapping already supports the max effort level. The level is silently dropped while building the allowed thinking profile, so it never reaches validation as a permitted value.

This appears related to #84349 (custom anthropic-messages providers missing Claude thinking profiles), but is a distinct, independently reproducible defect in the profile-builder: there is a wiring path for xhigh but no equivalent path for max, and the model compat.supportedReasoningEfforts array is not consulted for max at all.

Environment

  • OpenClaw 2026.5.28
  • A custom provider using api: "anthropic-messages" (self-hosted Anthropic-compatible proxy / gateway)
  • Models: claude-opus-4-8, claude-opus-4-8[1m], claude-opus-4-7, claude-opus-4-7[1m]
  • reasoning: true set on all of the above

Reproduction

  1. Configure a custom provider with api: "anthropic-messages" and a Claude Opus 4.8 model entry:
{
  "id": "claude-opus-4-8[1m]",
  "name": "Claude Opus 4.8 1M",
  "reasoning": true,
  "contextWindow": 1000000,
  "maxTokens": 64000,
  "compat": {
    "supportedReasoningEfforts": ["low", "medium", "high", "xhigh", "max"]
  }
}
  1. Restart the gateway so the config is reloaded.
  2. Attempt to select the max thinking level for this model (e.g. via /reasoning max or /think max).

Expected: max is accepted (it is declared in supportedReasoningEfforts, the ranks table defines it, and the Anthropic transport maps it).

Actual: Rejected with Thinking level "max" is not supported … Use one of: off, minimal, low, medium, high, xhigh. Note max is absent from the allowed list while xhigh is present.

Root cause analysis

The thinking-profile builder (resolveThinkingProfile, bundled thinking-*.js) constructs the allowed level set roughly as:

const profile = binaryDecision === true
  ? buildBinaryThinkingProfile(defaultLevel)
  : buildBaseThinkingProfile(defaultLevel); // [off, minimal, low, medium, high]

if (binaryDecision !== true && catalogSupportsXHigh(context.compat))
  appendProfileLevel(profile, "xhigh");

// (provider-hook xhigh path) …
return profile;

Two concrete gaps:

  1. No max append path. There is catalogSupportsXHigh(compat) (which scans compat.supportedReasoningEfforts for xhigh) and a corresponding appendProfileLevel(profile, "xhigh"). There is no catalogSupportsMax equivalent and no appendProfileLevel(profile, "max"). As a result, max can never be added to the base profile via catalog config.

  2. compat.supportedReasoningEfforts is not consulted for max. Declaring ["low","medium","high","xhigh","max"] in the model config has no effect for max, because only the hard-coded xhigh check reads that array. So the documented-looking config knob is effectively a no-op for max.

Supporting evidence that max is otherwise fully supported in the system:

  • THINKING_LEVEL_RANKS defines max: 70 (above xhigh: 60), so it is a first-class level for ordering.
  • The Anthropic transport mapping already handles it: case "max": return "max"; in mapThinkingLevelToEffort (i.e. max is passed through as a distinct effort, not clamped down to xhigh).
  • EXTENDED_THINKING_LEVELS includes "max".

So the only missing piece is wiring max from catalog config into the allowed profile for anthropic-messages providers.

Why this matters

Per Anthropic's documentation, the effort parameter supports max for Opus 4.7, Opus 4.6, and Sonnet 4.6 (and Opus 4.8 in the same adaptive-thinking family). Users routing Claude through a custom Anthropic-compatible endpoint currently cannot access the highest reasoning effort, even though both the backend and their explicit configuration request it. xhigh is the de-facto ceiling for these providers today, which silently caps reasoning quality below what the model supports.

Suggested fix

Mirror the existing xhigh handling for max, and/or honor compat.supportedReasoningEfforts generically:

// 1) Add a catalog check symmetric to catalogSupportsXHigh:
function catalogSupportsMax(compat) {
  const efforts = compat?.supportedReasoningEfforts;
  return Array.isArray(efforts) && efforts.some((e) => normalizeThinkLevel(e) === "max");
}

// 2) Append it when the catalog (or provider policy) allows it:
if (binaryDecision !== true && catalogSupportsMax(context.compat))
  appendProfileLevel(profile, "max");

Alternatively (more general, preferred): after the base profile is built, iterate compat.supportedReasoningEfforts and appendProfileLevel for any extended level present (xhigh, max), instead of special-casing only xhigh.

Additionally, for the adaptive-default Claude family, resolveClaudeThinkingProfile should include { id: "max" } in its levels (cf. #84349), so that providers which do hit the Claude profile hook also expose max.

Acceptance criteria

  • A Claude Opus 4.8 model on a custom anthropic-messages provider with compat.supportedReasoningEfforts containing max accepts /reasoning max / /think max.
  • max appears in the allowed levels list shown in the rejection/help message.
  • xhigh behavior is unchanged.
  • The selected max effort is forwarded to the Anthropic backend as max (not downgraded).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix max thinking level rejected for Claude Opus 4.8 via custom anthropic-messages provider despite config + backend support