Skip to content

[Bug]: lookupContextTokens() returns wrong contextWindow due to cross-provider model ID collision in MODEL_CACHE #17586

@githabideri

Description

@githabideri

Summary

Servus Peter and hi all!

I saw that my /status was messed up:

Image

and it semed to have counted much more than the 200k context

I investigated with Opus and it found the following below, but after fix and running compact once (it was stale before i assume) i got:

Image

here is Opus' take on it:

Summary

lookupContextTokens() in src/agents/context.ts populates MODEL_CACHE using modelRegistry.getAll(), which returns models from all built-in providers — including unconfigured ones. The cache is keyed by bare model ID without provider qualifier, so when multiple providers define the same model ID with different contextWindow values, the last one iterated overwrites the correct value.

src/agents/context.ts lines 19-25:
const models = modelRegistry.getAll() as ModelEntry[];
for (const m of models) {
if (!m?.id) continue;
if (typeof m.contextWindow === "number" && m.contextWindow > 0) {
MODEL_CACHE.set(m.id, m.contextWindow); // bare ID, no provider → last write wins
}
}

getAll() returns models from all built-in providers unconditionally, even those without configured authentication. The built-in model catalog defines claude-sonnet-4-5 under multiple providers with different context windows (200k for some, 1M for others). Since the cache key is just m.id, the last provider iterated overwrites the value.

Proposed Fix
Use getAvailable() instead of getAll() to filter to only providers with configured auth:

  • const models = modelRegistry.getAll() as ModelEntry[];
  • const models = modelRegistry.getAvailable() as ModelEntry[];
    This is safe because:

getAvailable() filters to "models that have auth configured" per the ModelRegistry interface
All callers of lookupContextTokens() already handle undefined gracefully (falling back to DEFAULT_CONTEXT_TOKENS)
Unconfigured providers' models would never be usable anyway
Impact
/status displays wrong context window (up to 5x off)
Session contextTokens field persisted with wrong value — survives compaction and session resets
Token budget calculations use incorrect context size
Affects any model ID that exists across multiple built-in providers with different context windows

Steps to reproduce

Fresh OpenClaw install, configure only Anthropic API key
Start the gateway
Send a message to any agent using claude-sonnet-4-5
Run /status in chat

Expected behavior

/status shows Context: .../200k (Anthropic's context window for claude-sonnet-4-5)

Actual behavior

/status shows Context: .../1.0m — a 5x overestimate of the context window. The wrong value gets persisted into the session entry's contextTokens field and affects all subsequent token budget calculations for that session.

OpenClaw version

v2026.2.6-3

Operating system

Ubuntu 24.04 LXC Conntainer

Install method

git clone

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions