Repository navigation
Routed metadata augmentation never backfills a context window onto a live row (latent; ruled out as the cause of #4944) #4971
Description
Client or integration
Codex CLI
Area
Catalog / models
Summary
augmentRoutedModelsWithMetadata appends generated-registry rows that the live provider list did
not return, and skips every id the live list did return:
// src/codex/catalog/routed-gather.ts:860-870
const out = [...models];
const seen = new Set(out.map(m => `${m.provider}/${m.id}`));
for (const provider of providerNames) {
if (!JAWCODE_CATALOG_AUGMENT_PROVIDERS.has(provider)) continue;
if (providers?.[provider]?.liveModels === false) continue;
const jawcodeProvider = resolveMetadataProvider(provider);
if (!jawcodeProvider) continue;
for (const meta of listModelMetadata(jawcodeProvider)) {
const key = `${provider}/${meta.id}`;
if (seen.has(key) ) continue;
seen.add(key);So a live row that arrives with no contextWindow keeps none, even when the registry holds a
published window for exactly that provider and id. The skip is append-only by construction: it
has no merge branch at all.
This is not the cause of #4944, and it should not be re-investigated as one. I ruled it out
while working that issue. The serialized catalog entry does not get its window from the
CatalogModel — applyCatalogMetadata (src/codex/catalog/parsing.ts:828-836) writes
context_window, max_context_window and auto_compact_token_limit onto the entry directly
from the generated table, keyed by provider and id, on both derive paths
(src/codex/catalog/derive-entry.ts:171 and :217). A row the registry knows therefore gets its
correct window regardless of this skip, and a row the registry does not know has nothing to merge.
Repairing the skip would have changed no catalog row in that report.
What it does affect is every consumer that reads CatalogModel.contextWindow instead of the
serialized entry. Combo member derivation carries its own 128k fallback at
src/codex/catalog/combo-member.ts:131, and routing capability resolution reads the config maps
at src/routing/capability.ts:174. Those paths see the un-backfilled value.
Filing it separately because "real defect, wrong suspect" is exactly the finding that disappears
when the issue it was found under gets closed.
Reproduction
Static, from source at dev a0f611d4aceb9476d44268e43722273b7b211846:
- Pick a provider in
JAWCODE_CATALOG_AUGMENT_PROVIDERS(src/codex/catalog/parsing.ts:178—
opencode-goanddeepseek) and an id the generated registry publishes acontextWindowfor. - Have the live
/v1/modelsresponse return that id with no context field, which is the normal
case for OpenCode Go. augmentRoutedModelsWithMetadatareachesif (seen.has(key)) continue;and theCatalogModel
keepscontextWindow: undefined.- Any consumer reading
CatalogModel.contextWindowrather than the serialized entry sees the
fallback instead of the published window.
Version
dev at a0f611d4aceb9476d44268e43722273b7b211846.
Operating system
Platform-independent.
Provider and model
Any provider in JAWCODE_CATALOG_AUGMENT_PROVIDERS; opencode-go is where it is easiest to see.
Logs or error output
No error is produced. The value is silently absent.
Screenshots and supporting files
None. Backend-only.
Redacted configuration
Not configuration-dependent beyond the provider being live-discovered with liveModels enabled.
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
Activity
lidge-jun commentedon Sep 18, 2026
Fixed on
devby #5023, squashed asbaae9057b61abda578f364cbe6041363c74c0865.First, a correction worth recording: #4962 does not close this, although it looks like it should. Its merged diff changed only the metadata snapshot, the generated table, the layout maps and its own regression file, and none of its four tests calls
augmentRoutedModelsWithMetadata.Second, both consumers named in this report are the wrong ones. Combo derivation resolves a provider-owned generated fallback before it ever looks at the live row, and
src/routing/capability.tsreads config maps plus serialized capability provenance rather than the gatheredCatalogModel.The real consumer is
buildClaudeContextWindows, which filters out routed rows with no positive window — so a published 1M OpenCode Go model could never receive its[1m]marker. Grok config injection, the management and Desktop projections, and several client exporters omit the field the same way.The fix adds a missing-value merge branch. A live positive window still wins, the seeded row is re-hinted so a configured window can still lower it, and
providerContextCapsstill caps it.Shipping in the next release off
dev.