Repository navigation
[Bug]: manual opencode-go modelContextWindows entries are reset after update #1409
Description
Client or integration
Codex App
Area
Catalog / models / config persistence
Current status
This issue remains open, but its scope is narrower than the original report suggested.
Current dev contains config-rebase work that fixed at least one confirmed management/save path which could lose provider configuration. However, the broader whole-document writer fix attempted in #1462 was closed without merge, and the original upgrade + later unrelated-write reproduction has not been proven fully covered.
Do not close this issue based only on the presence of the newer rebase-on-save machinery. The close condition is that the original user override survives the actual lifecycle described below, including upgrade/restart and an unrelated later save.
The architectural ambiguity behind stale-config rebasing is tracked separately in #1478.
Problem
An explicit user value under:
providers.opencode-go.modelContextWindows
was removed after upgrading and then performing a later unrelated config/provider write. The provider fell back to registry-seeded context metadata.
Registry defaults may seed missing values, but they must not overwrite or delete explicit user overrides.
Original reproduction
- Configure:
{
"providers": {
"opencode-go": {
"modelContextWindows": {
"deepseek-v4-flash": 900000
}
}
}
}- Run OpenCodex 2.11.0 and verify the override is effective.
- Upgrade to 2.11.1 and restart the daemon/app.
- Perform an unrelated provider/config write.
- Inspect
config.json. - The explicit
deepseek-v4-flashentry was gone andopencode-go.modelContextWindowscontained only registry-seeded values. - The generated catalog then fell back to its default context window.
The separate deepseek provider's context-window configuration was not affected in the original report.
Required behavior
- Explicit user
modelContextWindowsvalues survive upgrade and restart. - Registry defaults only fill genuinely missing values.
- An unrelated management/API/provider save must not remove an override that the writer did not intend to change.
- A deliberate deletion of an override must still remain possible and must not be resurrected by a rebase.
- Concurrent or independently loaded config writers must not silently erase unseen keys.
The last two requirements interact with the provenance problem in #1478. Fixing one by blindly treating every absent key as deletion, or every absent key as ignorance, is not sufficient.
Acceptance test
A regression should exercise the complete lifecycle rather than only a single helper:
seed explicit opencode-go modelContextWindows override
↓
load/start server
↓
perform registry/default reconciliation if applicable
↓
perform an unrelated management/config write
↓
reload from disk
↓
explicit override is still present and effective
Also cover deliberate deletion so the persistence fix does not make stale values impossible to remove.
Close condition
Close only when the original lifecycle is covered on current dev by a regression proving both preservation of explicit user overrides and intentional deletion semantics.
Related
- fix(config): rebase stale live saves #1462 - closed, unmerged broad config-writer attempt
- [Architecture]: define config rebase provenance for deletion vs unseen keys #1478 - config rebase provenance for deletion vs unseen keys
Activity
Ingwannu commentedon Aug 10, 2026
I checked current dev. src/providers/derive.ts:405 seeds modelContextWindows only when the entire user map is absent; src/router.ts:273-275 fills registry values beneath user entries; and src/server/management/provider-routes.ts:185-204 merges individual keys. None of those paths should replace the explicit deepseek-v4-flash value with the kimi-k3 registry seed.
The timing in this report, where a later unrelated full-config write makes the reset visible, matches the stale whole-document writer still tracked in #1273. The current sequence does not yet prove that it is the only cause, however. Please provide the exact order and redacted before/after snippets: which OCX or proxy processes were alive, whether the 900000 value was edited while the proxy was already running, which CLI or Dashboard action performed the unrelated write, and whether any restart happened between those steps. Config-file mtime and relevant mutation-generation log lines would also help.
Keeping this open separately until we can determine whether #1273 fully explains the write or whether the update path directly rewrites this field.
fix(openai-chat): refuse to emit an unnamed streamed tool call (#1531)
fix(providers): keep hand-edited context windows through a POST overw…
lidge-jun commentedon Aug 12, 2026
A real data-loss path in this area is fixed on
devby #1535, merged asb310d1826a2793c7cb1b9338f985c8c553e723b3. This does not close the issue — see the attribution note below.What was confirmed and fixed:
POST /api/providerslost hand-edited context windows on an overwrite. The dashboard's provider payload type has no member forcontextWindowormodelContextWindows, so the add/edit form structurally cannot send them; registry enrichment then filled the absent fields from the seed and the stored row became the seed. Foropencode-gothat seed is exactly{"kimi-k3": 262144}— precisely what you found in place of yourdeepseek-v4-flashentry.Both fields are now carried across an overwrite, following the precedent already in that function for
apiKeyPoolandmodelCosts: the form does not send them, so absence must mean "not carried", never "the user deleted it". Deletion stays an explicit null through PATCH.Why this is not enough to close the report. The reproduction I can demonstrate is a duplicate-name POST through the Add Provider modal. Your sequence was an upgrade, a daemon restart, and a later unrelated full-config write — and the dashboard's normal editing surfaces use PATCH, which already merged per key and preserved unmentioned entries. So the fixed path may not be the one you hit, and @Ingwannu's earlier note pointing at the stale whole-document writer in #1273 remains the leading hypothesis.
If you can still reproduce on a build containing
b310d1826, the most useful thing would be the exact order: which OCX or proxy processes were alive, whether the value was edited while the proxy was running, which CLI or Dashboard action performed the unrelated write, and whether a restart happened between those steps.Verification at the merged head:
tscexit 0;tests/management-provider-validation.test.ts60 pass / 0 fail; 60-file provider/config/management sweep 1023 pass / 0 fail; full suite 11,316 pass / 0 fail; 23 CI checks green including all Linux shards and macOS.fix(management): preserve the account-failover opt-out across a provi…
fix(catalog): fill registry capability seeds on the gather clone, not…
fix(catalog): keep per-model capability facts through registry enrich…
fix(management): preserve the account-failover opt-out across a provi…
fix(openai-chat): refuse to emit an unnamed streamed tool call (lidge…
fix(providers): keep hand-edited context windows through a POST overw…
fix(management): preserve the account-failover opt-out across a provi…
fix(catalog): keep per-model capability facts through registry enrich…