openclaw - 💡(How to fix) Fix Bug: Explicit thinkingLevel session override permanently reset to 'off' after each agent turn

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 an explicit thinkingLevel override is set on a session via sessions.patch (e.g. "high"), the value is correctly stored and displayed in the UI. However, as soon as the agent completes a turn (i.e. the first reply bubble appears), the thinkingLevel in the session store is permanently overwritten with "off".

This does not happen when thinkingLevel is left unset (i.e. null / "inherited"). In that case, the resolved level is correctly inherited from the agent/provider default (in our case "high" for Claude Sonnet 4.6 via GitHub Copilot), and the behavior persists across turns without issue.


Root Cause

Root cause (traced in source)

Fix Action

Fix / Workaround

When an explicit thinkingLevel override is set on a session via sessions.patch (e.g. "high"), the value is correctly stored and displayed in the UI. However, as soon as the agent completes a turn (i.e. the first reply bubble appears), the thinkingLevel in the session store is permanently overwritten with "off".

  1. Open any session with model github-copilot/claude-sonnet-4.6
  2. Set thinkingLevel to "high" via sessions.patch (or via the thinking selector in the Control UI)
  3. Confirm the selector shows high
  4. Send any prompt
  5. As soon as the reply bubble appears, observe the thinking selector jump to off
  6. Check session state — thinkingLevel is now "off" in the store
  • sessions.patch { thinkingLevel: "high" } should persist across turns
  • If a thinking level is not supported at runtime for a given model, the session store should not be mutated — the fallback should only apply for that turn
  • Alternatively: the UI should be informed of the remapping so it can display the actual effective level

Code Example

// ~line 2837
const thinkingLevelSupported = isThinkingLevelSupported({
  provider,
  model,
  level: resolvedThinkLevel,
  catalog: thinkingCatalog
});

// ~line 2848 — if not supported, fallback is resolved
if (!thinkingLevelSupported) {
  const fallbackThinkLevel = resolveSupportedThinkingLevel({ ... });

  if (fallbackThinkLevel !== resolvedThinkLevel) {
    resolvedThinkLevel = fallbackThinkLevel;

    // ← THIS permanently mutates the session store:
    if (sessionEntry && sessionStore && sessionKey && sessionEntry.thinkingLevel === previousThinkLevel) {
      sessionEntry.thinkingLevel = fallbackThinkLevel;  // writes "off" back to store
      sessionEntry.updatedAt = Date.now();
      sessionStore[sessionKey] = sessionEntry;
      await updateSessionStore(storePath, (store) => {
        store[sessionKey] = sessionEntry;
      });
    }
  }
}
RAW_BUFFERClick to expand / collapse

Bug: Explicit thinkingLevel session override is permanently reset to off after each agent turn

OpenClaw version: 2026.5.27 Model: github-copilot/claude-sonnet-4.6 Channel: WebChat (Control UI) and custom Voice UI (both affected equally)


Description

When an explicit thinkingLevel override is set on a session via sessions.patch (e.g. "high"), the value is correctly stored and displayed in the UI. However, as soon as the agent completes a turn (i.e. the first reply bubble appears), the thinkingLevel in the session store is permanently overwritten with "off".

This does not happen when thinkingLevel is left unset (i.e. null / "inherited"). In that case, the resolved level is correctly inherited from the agent/provider default (in our case "high" for Claude Sonnet 4.6 via GitHub Copilot), and the behavior persists across turns without issue.


Steps to reproduce

  1. Open any session with model github-copilot/claude-sonnet-4.6
  2. Set thinkingLevel to "high" via sessions.patch (or via the thinking selector in the Control UI)
  3. Confirm the selector shows high
  4. Send any prompt
  5. As soon as the reply bubble appears, observe the thinking selector jump to off
  6. Check session state — thinkingLevel is now "off" in the store

Repeat: setting thinkingLevel back to "high" and sending another prompt resets it to "off" again every single time.

Using "inherited" (i.e. null / no override) works correctly and persists.


Root cause (traced in source)

In get-reply-DuA7xbHV.js, around the thinking-level resolution and fallback block:

// ~line 2837
const thinkingLevelSupported = isThinkingLevelSupported({
  provider,
  model,
  level: resolvedThinkLevel,
  catalog: thinkingCatalog
});

// ~line 2848 — if not supported, fallback is resolved
if (!thinkingLevelSupported) {
  const fallbackThinkLevel = resolveSupportedThinkingLevel({ ... });

  if (fallbackThinkLevel !== resolvedThinkLevel) {
    resolvedThinkLevel = fallbackThinkLevel;

    // ← THIS permanently mutates the session store:
    if (sessionEntry && sessionStore && sessionKey && sessionEntry.thinkingLevel === previousThinkLevel) {
      sessionEntry.thinkingLevel = fallbackThinkLevel;  // writes "off" back to store
      sessionEntry.updatedAt = Date.now();
      sessionStore[sessionKey] = sessionEntry;
      await updateSessionStore(storePath, (store) => {
        store[sessionKey] = sessionEntry;
      });
    }
  }
}

The fallback path is triggered because isThinkingLevelSupported returns false for level: "high" with github-copilot/claude-sonnet-4.6 at runtime — even though the provider plugin's resolveThinkingProfile clearly includes { id: "high" } in its levels array (confirmed in github-copilot/index.js).

The result is that the fallback resolves to "off" and is written back into the persistent session store, silently destroying the user's explicit override on every turn.


Expected behavior

  • sessions.patch { thinkingLevel: "high" } should persist across turns
  • If a thinking level is not supported at runtime for a given model, the session store should not be mutated — the fallback should only apply for that turn
  • Alternatively: the UI should be informed of the remapping so it can display the actual effective level

Additional context

  • "inherited" (no override / null) works correctly — the resolved level is "high" via provider default and is never mutated
  • The bug is reproducible in both the official Control UI (WebChat) and a custom Voice UI built on the Gateway Bridge
  • The GitHub Copilot provider plugin explicitly lists "high" as a supported level for claude-sonnet-4.6, so the runtime isThinkingLevelSupported check appears to be disagreeing with the plugin's own profile declaration
  • This has been present since at least v2026.4.22 and persists through v2026.5.27

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…

FAQ

Expected behavior

  • sessions.patch { thinkingLevel: "high" } should persist across turns
  • If a thinking level is not supported at runtime for a given model, the session store should not be mutated — the fallback should only apply for that turn
  • Alternatively: the UI should be informed of the remapping so it can display the actual effective level

Still need to ship something?

×6

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

Back to top recommendations

TRENDING