openclaw - ✅(Solved) Fix BUG: Tool-result guard ignores resolved contextTokens budget when contextWindow is lower [3 pull requests, 3 comments, 4 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#74917Fetched 2026-05-01 05:39:57
View on GitHub
Comments
3
Participants
4
Timeline
12
Reactions
2
Author
Timeline (top)
commented ×3cross-referenced ×3labeled ×2closed ×1

When a configured model has a larger effective contextTokens budget than its resolved contextWindow value, OpenClaw displays/uses the larger runtime budget in some paths but the tool-result context guard still sizes itself from model.contextWindow. This can trigger premature tool-loop overflow/compaction at the smaller contextWindow scale.

Error Message

All runtime paths that enforce context limits should use the same resolved effective context budget. If contextTokens is the effective runtime budget, the tool-result context guard should use that resolved value, or OpenClaw should warn/reject inconsistent model metadata instead of silently enforcing a smaller guard budget.

Root Cause

When a configured model has a larger effective contextTokens budget than its resolved contextWindow value, OpenClaw displays/uses the larger runtime budget in some paths but the tool-result context guard still sizes itself from model.contextWindow. This can trigger premature tool-loop overflow/compaction at the smaller contextWindow scale.

Fix Action

Fixed

PR fix notes

PR #74934: fix: tool-result context guard uses contextTokenBudget when available [AI-assisted]

Description (problem / solution / changelog)

Root Cause

installToolResultContextGuard in src/agents/pi-embedded-runner/run/attempt.ts (line ~1476) was installed with params.model.contextWindow as the token budget. However, the resolved runtime budget lives in params.contextTokenBudget, which can differ from contextWindow when the model metadata has contextTokens > contextWindow.

All other budget-sensitive paths in the same function (SessionManager at line 1272, context engine hooks at lines 2641/2648/2654) already use params.contextTokenBudget. The guard was the only path that diverged, causing premature tool-result compaction when contextWindow < contextTokenBudget.

Fix

Prepend params.contextTokenBudget ?? to the existing fallback chain so the guard uses the same resolved budget as every other path. When contextTokenBudget is undefined (legacy/unresolved cases), behavior is unchanged.

Regression Test Plan

  • Existing tool-result-context-guard.test.ts and session-tool-result-guard.test.ts cover guard installation and threshold behavior.
  • The fix only changes which value is passed to an existing parameter; no new code paths are introduced.
  • Manual verification: configure a model with contextTokens: 1000000 and contextWindow: 200000, run a tool-heavy session, and confirm compaction threshold aligns with the 1M token budget rather than the 200K window.

Security Impact

None. This change only affects which internally-resolved numeric budget value is passed to an existing guard. No new inputs, no authentication changes, no network surface changes.

Fixes #74917

Changed files

  • src/agents/pi-embedded-runner/run/attempt.ts (modified, +4/-1)

PR #74978: fix(agents): use resolved contextTokenBudget in tool-result context guard

Description (problem / solution / changelog)

Summary

When a model's contextTokens exceeds its contextWindow, the non-context-engine tool-result guard was incorrectly using the smaller contextWindow value to derive its overflow threshold. This caused premature tool-loop overflow/compaction even though the runtime budget (resolved from contextTokens) indicated available capacity.

Root Cause

installToolResultContextGuard was installed with:

contextWindowTokens: params.model.contextWindow ?? params.model.maxTokens ?? DEFAULT_CONTEXT_TOKENS

But the rest of the attempt layer (session manager at line 1272, context-engine loop hook at line 1490) already uses params.contextTokenBudget — the resolved runtime budget from resolveContextWindowInfo.

Fix

Add params.contextTokenBudget as the first fallback in the nullish coalescing chain:

contextWindowTokens: params.contextTokenBudget ?? params.model.contextWindow ?? params.model.maxTokens ?? DEFAULT_CONTEXT_TOKENS

When contextTokenBudget is defined (the common case — set from ctxInfo.tokens in run.ts:988), the guard now uses the same resolved budget as every other context-aware path. When undefined, behavior is unchanged.

Testing

  • TypeScript compilation passes cleanly
  • Change is a single-line addition to the existing fallback chain
  • Acceptance: pnpm test src/agents/pi-embedded-runner/tool-result-context-guard.test.ts

Fixes #74917

Changed files

  • src/agents/pi-embedded-runner/run/attempt.ts (modified, +4/-1)

PR #75092: fix(agents): use resolved budget for tool-result guard

Description (problem / solution / changelog)

Fixes #74917.

Summary

  • Pass the resolved contextTokenBudget into the non-owner tool-result context guard.
  • Add regression coverage where the resolved budget is smaller than the model-declared context window.

Validation

  • pnpm exec oxfmt --check --threads=1 src/agents/pi-embedded-runner/run/attempt.ts src/agents/pi-embedded-runner/run/attempt.spawn-workspace.context-engine.test.ts
  • pnpm test src/agents/pi-embedded-runner/run/attempt.spawn-workspace.context-engine.test.ts src/agents/pi-embedded-runner/tool-result-context-guard.test.ts src/agents/pi-embedded-runner/run/preemptive-compaction.test.ts -- --reporter=verbose
  • pnpm check:changed
  • git diff --check

AI-assisted with OpenAI Codex.

Changed files

  • src/agents/pi-embedded-runner/run/attempt.spawn-workspace.context-engine.test.ts (modified, +36/-0)
  • src/agents/pi-embedded-runner/run/attempt.ts (modified, +4/-1)

Code Example

Evidence from local investigation, sanitized:

Resolved model metadata before local correction:

{
  "key": "openai-codex/gpt-5.5",
  "contextWindow": 200000,
  "contextTokens": 1000000
}

Runtime/effective-model path resolves ctxInfo.tokens from contextTokens, but only lowers contextWindow when the resolved budget is smaller:
const effectiveModel = ctxInfo.tokens < (params.runtimeModel.contextWindow ?? Infinity) ? {
  ...params.runtimeModel,
  contextWindow: ctxInfo.tokens
} : params.runtimeModel;

Tool-result guard installation uses model.contextWindow instead of the resolved context token budget:

installToolResultContextGuard({
  agent: activeSession.agent,
  contextWindowTokens: Math.max(1, Math.floor(params.model.contextWindow ?? params.model.maxTokens ?? 2e5))
});

Observed threshold math matched the premature behavior:

Guard using contextWindow: 200000 * 4 * 0.9 = 720000 estimated chars
Guard using configured contextTokens: 1000000 * 4 * 0.9 = 3600000 estimated chars
After local correction to align both fields, the model resolved as contextWindow=1050000 and contextTokens=1050000.
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When a configured model has a larger effective contextTokens budget than its resolved contextWindow value, OpenClaw displays/uses the larger runtime budget in some paths but the tool-result context guard still sizes itself from model.contextWindow. This can trigger premature tool-loop overflow/compaction at the smaller contextWindow scale.

Steps to reproduce

  1. Configure a model entry where contextTokens is larger than contextWindow, or where contextTokens is set but contextWindow remains at a provider fallback value. Example observed resolved metadata before local correction: contextWindow=2000 and contextTokens=1000 for openai-codex/gpt-5.5.
  2. Use that model in an embedded-runer session with default/tool-result context guard behavior.
  3. Accumulate tool-result history large enough to exceed the guard threshold derived from contextWindow but still below the threshold implied by contextTokens. In the observed case, the guard threshold was approximately 2000 * 4 * 0.9 = 72000 estimated chars, while the configured runtime budget implied roughly 1000 * 4 * 0.9 = 36000 estimated chars.
  4. Observe premature tool-loop overflow/compaction behavior even though session status/runtime budget indicates substantially more remaining context.

Expected behavior

All runtime paths that enforce context limits should use the same resolved effective context budget. If contextTokens is the effective runtime budget, the tool-result context guard should use that resolved value, or OpenClaw should warn/reject inconsistent model metadata instead of silently enforcing a smaller guard budget.

Actual behavior

The session/runtime budget path resolves the larger contextTokens value, but installToolResultContextGuard is installed with contextWindowTokens derived from params.model.contextWindow. When contextWindow is lower than contextTokens, the guard fires at the lower contextWindow scale.

OpenClaw version

2026.4.26

Operating system

Ubuntu 26.04 LTS

Install method

Package install (pnpm, global/system install)

Model

openai-codex/gpt-5.5

Provider / routing chain

OpenClaw embedded runner with the openai-codex provider

Additional provider/model setup details

Configured model metadata included contextTokens larger than contextWindow. No secrets or auth details are relevant.

Logs, screenshots, and evidence

Evidence from local investigation, sanitized:

Resolved model metadata before local correction:

{
  "key": "openai-codex/gpt-5.5",
  "contextWindow": 200000,
  "contextTokens": 1000000
}

Runtime/effective-model path resolves ctxInfo.tokens from contextTokens, but only lowers contextWindow when the resolved budget is smaller:
const effectiveModel = ctxInfo.tokens < (params.runtimeModel.contextWindow ?? Infinity) ? {
  ...params.runtimeModel,
  contextWindow: ctxInfo.tokens
} : params.runtimeModel;

Tool-result guard installation uses model.contextWindow instead of the resolved context token budget:

installToolResultContextGuard({
  agent: activeSession.agent,
  contextWindowTokens: Math.max(1, Math.floor(params.model.contextWindow ?? params.model.maxTokens ?? 2e5))
});

Observed threshold math matched the premature behavior:

Guard using contextWindow: 200000 * 4 * 0.9 = 720000 estimated chars
Guard using configured contextTokens: 1000000 * 4 * 0.9 = 3600000 estimated chars
After local correction to align both fields, the model resolved as contextWindow=1050000 and contextTokens=1050000.

Impact and severity

Users who configure a larger contextTokens budget can see status/runtime context accounting that suggests there is room remaining, while tool-loop overflow/compaction is enforced against a smaller contextWindow value. This causes premature compaction/overflow in tool-heavy long-context sessions and makes the effective context behavior hard to diagnose.

Additional information

Suggested fix: pass the resolved contextTokenBudget/ctxInfo.tokens into installToolResultContextGuard when available, or normalize/validate configured model metadata so contextTokens and contextWindow cannot silently diverge in a way that affects enforcement paths. This report does not claim that any upstream provider accepts a full maximum-window live request; it is limited to OpenClaw internal context-budget consistency.

extent analysis

TL;DR

Pass the resolved context token budget to installToolResultContextGuard to ensure consistency in context limit enforcement.

Guidance

  • Verify that contextTokens and contextWindow values are consistent in the model metadata to prevent silent divergence.
  • Update the installToolResultContextGuard function to use the resolved contextTokenBudget or ctxInfo.tokens instead of params.model.contextWindow.
  • Consider normalizing or validating configured model metadata to prevent inconsistent contextTokens and contextWindow values.
  • Review the threshold math calculation to ensure it aligns with the resolved context token budget.

Example

installToolResultContextGuard({
  agent: activeSession.agent,
  contextWindowTokens: Math.max(1, Math.floor(ctxInfo.tokens ?? params.model.contextWindow ?? 2e5))
});

Notes

This fix assumes that the ctxInfo.tokens value is available and accurately represents the resolved context token budget. Additional validation or error handling may be necessary to ensure the fix works correctly in all scenarios.

Recommendation

Apply the suggested fix by passing the resolved context token budget to installToolResultContextGuard to ensure consistency in context limit enforcement. This will help prevent premature tool-loop overflow/compaction and make the effective context behavior easier to diagnose.

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

All runtime paths that enforce context limits should use the same resolved effective context budget. If contextTokens is the effective runtime budget, the tool-result context guard should use that resolved value, or OpenClaw should warn/reject inconsistent model metadata instead of silently enforcing a smaller guard budget.

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 - ✅(Solved) Fix BUG: Tool-result guard ignores resolved contextTokens budget when contextWindow is lower [3 pull requests, 3 comments, 4 participants]