You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
model_catalog_json is resolved once at startup: context window cannot follow a provider switch, so Codex over-fills the prompt and upstream returns 400 #47917
model_catalog_json is resolved once, at process start. When the provider changes behind a running process — e.g. a local proxy that rewrites config.toml (CC Switch in "proxy takeover" mode) — the process keeps using the old catalog. So per-provider/per-model metadata, most importantly context_window, does not follow the switch.
When the same model name is served by providers with different limits, a single catalog can only hold one number. Codex trusts the larger value, never triggers auto-compaction, and the smaller provider rejects the request.
Observed (live, this session)
Model deepseek-flash; catalog context_window = 1000000 (as advertised by one provider). After switching to a second provider that serves the same model name with a real limit of 262144:
time
thread
upstream limit
prompt tokens
02:42:04
01a0d4b0…
262144
262145
02:47:03
01a0d4be…
262144
262145
02:47:39
01a0d4be…
262144
262145
02:52:33
01a0d4be…
262144
262145
Upstream error:
This model's maximum context length is 262144 tokens.
However, you requested 0 output tokens and your prompt contains at least 262145 input tokens.
Impact
Any thread longer than the smaller provider's limit becomes unusable on that provider, and Codex never auto-compacts because it believes it has ~1M tokens. From the user's side this looks like "the context size doesn't follow the provider", with no visible cause.
Requested
Any of:
per-provider catalog scoping — e.g. model_providers.<id>.model_catalog_json, or per-provider model entries inside one catalog;
re-resolve the model catalog when config.toml changes (the desktop app / app-server currently does not);
at minimum, document that model_catalog_json is read at startup so users know a restart is required after switching providers.
Workaround we use
Set each entry to the minimum across all providers that serve that model name, so the value is safe everywhere:
deepseek-flash 1000000 -> 262144 (effective 249036 at 95%)
deepseek-v4.1-flash 300000 -> 262144 (effective 249036 at 95%)
Cost: on the provider that really allows ~1M, compaction now happens far earlier than necessary.
The app runs a long-lived app-server daemon (~/.codex/app-server-daemon/, control socket under ~/.codex/app-server-control/) and it survives app restarts. It reads the catalog once, at process start, and never refreshes it: with model_catalog_json set, the manager is a StaticModelsManager, and refresh_if_new_etag is a no-op there.
Timeline from this machine: the override was written to the catalog at 2026-09-29 17:50, and the daemon had been up since 2026-09-27 08:58. codex debug models (fresh process) saw the new catalog; the daemon served the old one. codex app-server daemon restart fixed it immediately. An app relaunch does nothing, since the daemon is untouched by it.
This affects more than context_window. In our case the stale snapshot also meant auto_review_model_override never applied, so approvals_reviewer = "auto_review" kept sending codex-auto-review to a provider that doesn't serve it, and every escalation failed closed (see #31255).
Confirming this behavior and sharing a temporary automated workaround on Windows while upstream hot-reloading is pending:
Root Cause Confirmation
In the current architecture, the persistent app-server --managed-daemon resolves config.toml and model_catalog_json strictly once at startup. When external switchers/proxies rewrite these configuration files on disk, the running daemon remains oblivious to the changes. As a result, the in-memory model catalog, reasoning tiers, and context window limits stay locked to the previous provider.
Since the app-server automatically recovers and reconnects active client sessions upon restart, we implemented a lightweight background watcher on config.toml and cc-switch-model-catalog.json:
Debounce (4s): Watches the provider signature (model|name|base_url|catalog_sha256) with a 4-second cooldown to ensure external tools finish writing all files.
Seamless Client Recovery: Active Codex TUI / CLI clients experience a brief ~1-2s disconnect and automatically reconnect with the updated model catalog and context limits fully applied.
A native SIGHUP / RPC signal (e.g. codex app-server daemon reload-config) or automatic file-watching on the catalog would be the ideal long-term solution.
Activity
l33tdawg commentedon Sep 29, 2026
More desktop-app evidence, and a workaround:
The app runs a long-lived app-server daemon (
~/.codex/app-server-daemon/, control socket under~/.codex/app-server-control/) and it survives app restarts. It reads the catalog once, at process start, and never refreshes it: withmodel_catalog_jsonset, the manager is aStaticModelsManager, andrefresh_if_new_etagis a no-op there.Timeline from this machine: the override was written to the catalog at 2026-09-29 17:50, and the daemon had been up since 2026-09-27 08:58.
codex debug models(fresh process) saw the new catalog; the daemon served the old one.codex app-server daemon restartfixed it immediately. An app relaunch does nothing, since the daemon is untouched by it.This affects more than
context_window. In our case the stale snapshot also meantauto_review_model_overridenever applied, soapprovals_reviewer = "auto_review"kept sendingcodex-auto-reviewto a provider that doesn't serve it, and every escalation failed closed (see #31255).babelllll commentedon Sep 30, 2026
Confirming this behavior and sharing a temporary automated workaround on Windows while upstream hot-reloading is pending:
Root Cause Confirmation
In the current architecture, the persistent
app-server --managed-daemonresolvesconfig.tomlandmodel_catalog_jsonstrictly once at startup. When external switchers/proxies rewrite these configuration files on disk, the running daemon remains oblivious to the changes. As a result, the in-memory model catalog, reasoning tiers, and context window limits stay locked to the previous provider.Automated Workaround (File Watcher + Daemon Hot-Swap)
Since the app-server automatically recovers and reconnects active client sessions upon restart, we implemented a lightweight background watcher on
config.tomlandcc-switch-model-catalog.json:model|name|base_url|catalog_sha256) with a 4-second cooldown to ensure external tools finish writing all files.codex.exe app-server daemon stop(with a-HardStopfallback if attached clients delay shutdown) and restarts the daemon with-WindowStyle Hiddento prevent visible console popup storms on child process spawns (related to Windows: app-server daemon opens a visible console window for every hook and shell command it runs #44768).A native SIGHUP / RPC signal (e.g.
codex app-server daemon reload-config) or automatic file-watching on the catalog would be the ideal long-term solution.