openclaw - 💡(How to fix) Fix [Bug]: agents.list[].contextTokens is read at runtime but stripped on hot reload — /status always falls back to 200k [1 participants]

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…
GitHub stats
openclaw/openclaw#70692Fetched 2026-04-24 05:54:37
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0

A per-agent contextTokens override is read by the runtime in at least eight locations (including /status rendering), but the JSON Schema at agents.list[] does not declare it. The config watcher strips it on hot reload, so the field cannot be persisted. As a result, /status falls back to a hardcoded 2e5 (200 000) token default, even for models that declare contextWindow: 1048576 in their provider entry.

Root Cause

/status shows 200k regardless of the underlying model's declared contextWindow. The hardcoded fallbackContextTokens: 2e5 path is taken because:

Fix Action

Fix / Workaround

No workaround available other than ignoring the display; adding contextTokens to the config is silently reverted on every hot reload.

Code Example

"models": {
     "providers": {
       "google": {
         "models": [
           {
             "id": "gemini-3-flash-preview",
             "contextWindow": 1048576,
             "maxTokens": 65536
           }
         ]
       }
     }
   },
   "agents": {
     "list": [
       {
         "id": "chat",
         "name": "Clawdy",
         "model": { "primary": "google/gemini-3-flash-preview" }
       }
     ]
   }

---

# 8 runtime read sites for per-agent contextTokens override
# (paths relative to /opt/homebrew/lib/node_modules/openclaw/dist/)

agent-command-CwB3KOfd.js:800:                 contextTokensOverride: agentCfg?.contextTokens,
directive-handling.persist.runtime-Cm0RA2L6.js:139:  contextTokensOverride: agentCfg?.contextTokens,
get-reply-Cld8oTG6.js:1203:   let contextTokens = useFastReplyRuntime ? agentCfg?.contextTokens ?? 2e5 : resolveContextTokens({ ... });
get-reply-Cld8oTG6.js:2412:   agentCfgContextTokens: agentCfg?.contextTokens,
model-selection-DpNW4nwC.js:393:  return params.agentCfg?.contextTokens ?? resolveContextTokensForModel({ ... });
server.impl-DLF59fRo.js:3699: const contextTokens = resolvePositiveContextTokens(prepared.agentCfg?.contextTokens) ?? ... ?? 2e5;
status-message-NCClW_Lx.js:295:  contextTokensOverride: persistedContextTokens ?? args.agent?.contextTokens,
status-text-21L561ti.js:180:  explicitConfiguredContextTokens: typeof agentDefaults.contextTokens === "number" && agentDefaults.contextTokens > 0 ? agentDefaults.contextTokens : void 0,

# Override path honored (context-C_eSb8DM.js:231)
if (typeof params.contextTokensOverride === "number" && params.contextTokensOverride > 0) return params.contextTokensOverride;

# Hardcoded 200k fallback applied by three callers
session-store.runtime-C6iyhqIz.js:34:  fallbackContextTokens: 2e5,
status-message-NCClW_Lx.js:296:        fallbackContextTokens: 2e5,
status.summary-QdXRO1GA.js:107:        fallbackContextTokens: 2e5,

# Schema is strict (additionalProperties: false appears 819 times in runtime-schema-*.js)
# and agents.list[].contextTokens is not declared in the flat-key map that
# runtime-schema exposes for config audit/persistence:
grep -nE '"agents\.list\[\]\.contextTokens"' runtime-schema-CrEOE13h.js   # no match
grep -nE '"agents\.defaults\.contextTokens"' runtime-schema-CrEOE13h.js   # no match

# Repro evidence: write override, observe strip within seconds
# T+0s:
#   "contextTokens": 1048576  (present after Edit)
# T+3s after gateway `[reload] config change detected` + `[reload] config hot reload applied`:
#   field gone; only model/heartbeat/tools remain
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

A per-agent contextTokens override is read by the runtime in at least eight locations (including /status rendering), but the JSON Schema at agents.list[] does not declare it. The config watcher strips it on hot reload, so the field cannot be persisted. As a result, /status falls back to a hardcoded 2e5 (200 000) token default, even for models that declare contextWindow: 1048576 in their provider entry.

Steps to reproduce

  1. Install [email protected] (homebrew npm global).
  2. Configure an agent whose primary model has a large context window. In ~/.openclaw/openclaw.json:
    "models": {
      "providers": {
        "google": {
          "models": [
            {
              "id": "gemini-3-flash-preview",
              "contextWindow": 1048576,
              "maxTokens": 65536
            }
          ]
        }
      }
    },
    "agents": {
      "list": [
        {
          "id": "chat",
          "name": "Clawdy",
          "model": { "primary": "google/gemini-3-flash-preview" }
        }
      ]
    }
  3. Run /status in that agent's session. Observed: Context … / 200k, not 1M.
  4. Attempt to override by adding "contextTokens": 1048576 to the agent entry and saving. Within ~3 seconds the gateway config watcher fires [reload] config change detected and the contextTokens key disappears from the file on disk. /status still reports 200k.

Expected behavior

When a provider declares contextWindow: 1048576 for the model an agent runs, /status should report the declared window (1M), not the hardcoded 200k fallback. Equivalently: either the provider-declared contextWindow should reach resolveContextTokensForModel, or agents.list[].contextTokens should be a whitelisted schema field so users can set it explicitly.

Actual behavior

/status shows 200k regardless of the underlying model's declared contextWindow. The hardcoded fallbackContextTokens: 2e5 path is taken because:

  1. resolveContextTokensForModel (context-C_eSb8DM.js:230-254) falls through to params.fallbackContextTokens.
  2. All three callers that hit this path pass fallbackContextTokens: 2e5.
  3. The only way to bypass it is contextTokensOverride, which reads from agentCfg?.contextTokens — a field the schema strips on hot reload.

OpenClaw version

2026.4.21

Operating system

macOS 15 (Darwin 25.4.0, arm64 / Apple M4)

Install method

npm install -g openclaw via /opt/homebrew/bin/npm (Homebrew Node).

Model

google/gemini-3-flash-preview (provider entry declares contextWindow: 1048576). Also observed with google/gemini-3.1-pro-preview (same 1M window declared, same 200k symptom).

Provider / routing chain

openclaw -> google (generativelanguage.googleapis.com/v1beta) — default direct route.

Additional provider/model setup details

Two agents exhibit the symptom:

  • Clawdy (id=chat) with primary google/gemini-3-flash-preview.
  • Iris (id=vision) with primary google/gemini-3.1-pro-preview.

Both provider entries in models.providers.google.models[] have contextWindow: 1048576. No agents.defaults.contextTokens or agents.list[].contextTokens override can be persisted (see repro step 4).

Logs, screenshots, and evidence

# 8 runtime read sites for per-agent contextTokens override
# (paths relative to /opt/homebrew/lib/node_modules/openclaw/dist/)

agent-command-CwB3KOfd.js:800:                 contextTokensOverride: agentCfg?.contextTokens,
directive-handling.persist.runtime-Cm0RA2L6.js:139:  contextTokensOverride: agentCfg?.contextTokens,
get-reply-Cld8oTG6.js:1203:   let contextTokens = useFastReplyRuntime ? agentCfg?.contextTokens ?? 2e5 : resolveContextTokens({ ... });
get-reply-Cld8oTG6.js:2412:   agentCfgContextTokens: agentCfg?.contextTokens,
model-selection-DpNW4nwC.js:393:  return params.agentCfg?.contextTokens ?? resolveContextTokensForModel({ ... });
server.impl-DLF59fRo.js:3699: const contextTokens = resolvePositiveContextTokens(prepared.agentCfg?.contextTokens) ?? ... ?? 2e5;
status-message-NCClW_Lx.js:295:  contextTokensOverride: persistedContextTokens ?? args.agent?.contextTokens,
status-text-21L561ti.js:180:  explicitConfiguredContextTokens: typeof agentDefaults.contextTokens === "number" && agentDefaults.contextTokens > 0 ? agentDefaults.contextTokens : void 0,

# Override path honored (context-C_eSb8DM.js:231)
if (typeof params.contextTokensOverride === "number" && params.contextTokensOverride > 0) return params.contextTokensOverride;

# Hardcoded 200k fallback applied by three callers
session-store.runtime-C6iyhqIz.js:34:  fallbackContextTokens: 2e5,
status-message-NCClW_Lx.js:296:        fallbackContextTokens: 2e5,
status.summary-QdXRO1GA.js:107:        fallbackContextTokens: 2e5,

# Schema is strict (additionalProperties: false appears 819 times in runtime-schema-*.js)
# and agents.list[].contextTokens is not declared in the flat-key map that
# runtime-schema exposes for config audit/persistence:
grep -nE '"agents\.list\[\]\.contextTokens"' runtime-schema-CrEOE13h.js   # no match
grep -nE '"agents\.defaults\.contextTokens"' runtime-schema-CrEOE13h.js   # no match

# Repro evidence: write override, observe strip within seconds
# T+0s:
#   "contextTokens": 1048576  (present after Edit)
# T+3s after gateway `[reload] config change detected` + `[reload] config hot reload applied`:
#   field gone; only model/heartbeat/tools remain

Impact and severity

  • Affected: any user running an agent on a model whose provider entry declares contextWindow > 200000 (Gemini 3 Flash/Pro, Claude Opus via OpenRouter at 1M, GPT-5.4 via OpenRouter at 1.05M, etc.). Reproduced on two agents (Clawdy, Iris) in our setup; one user.
  • Severity: Moderate — misleading UX. /status systematically understates the context budget, which pushes users toward premature /compact or a needless model switch. Secondary effect: session-store.runtime and status.summary also use the 200k fallback for internal budgeting, so large-context models may be over-truncated.
  • Frequency: Deterministic (100% reproducible on every /status call and every persistence attempt).
  • Consequence: Incorrect status reporting; potential internal over-truncation when the runtime falls through to the 200k fallback instead of the real provider-declared window.

Additional information

Two possible fixes (not mutually exclusive):

  1. Prefer provider-declared contextWindow in resolveContextTokensForModel. The resolveConfiguredProviderContextTokens(cfg, explicitProvider, ref.model) path at context-C_eSb8DM.js:240 already looks up the correct 1048576 value from config, but does not appear to be hit for the status-message/session-store/status.summary callers. If they resolved via this path, the fallback would be unnecessary for correctly declared providers.
  2. Whitelist contextTokens on agents.list[] (and optionally agents.defaults) in the JSON Schema so the field that eight runtime call sites already read can actually be persisted by users as an explicit override.

(1) alone covers the common case without requiring users to know about a second knob. (2) is still useful for edge cases where a user wants a smaller effective window than the provider declares.

No workaround available other than ignoring the display; adding contextTokens to the config is silently reverted on every hot reload.

extent analysis

TL;DR

To fix the issue, either prefer the provider-declared contextWindow in resolveContextTokensForModel or whitelist contextTokens on agents.list[] in the JSON Schema.

Guidance

  • Review the resolveContextTokensForModel function to ensure it correctly resolves the provider-declared contextWindow for the status-message, session-store, and status.summary callers.
  • Consider whitelisting contextTokens on agents.list[] in the JSON Schema to allow users to persist explicit overrides.
  • Verify that the contextTokensOverride path is honored in the context-C_eSb8DM.js file.
  • Check the runtime-schema-CrEOE13h.js file to confirm that agents.list[].contextTokens is not declared in the flat-key map.

Example

No code snippet is provided as the issue is related to the JSON Schema and the resolveContextTokensForModel function, which requires a more in-depth review of the codebase.

Notes

The issue is specific to the OpenClaw version 2026.4.21 and the google/gemini-3-flash-preview and google/gemini-3.1-pro-preview models. The fix may not apply to other versions or models.

Recommendation

Apply a workaround by ignoring the display issue until a permanent fix is available, as there is no known workaround that can be implemented without modifying the codebase.

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

When a provider declares contextWindow: 1048576 for the model an agent runs, /status should report the declared window (1M), not the hardcoded 200k fallback. Equivalently: either the provider-declared contextWindow should reach resolveContextTokensForModel, or agents.list[].contextTokens should be a whitelisted schema field so users can set it explicitly.

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 [Bug]: agents.list[].contextTokens is read at runtime but stripped on hot reload — /status always falls back to 200k [1 participants]