Whole-config rejection without last-good fallback kills all running sessions when a concurrent writer leaves a transient partial state in opencode.jsonc
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 48/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- json, typescript
- Ambito
- backend
Direzione di ricerca
Start with packages/core/src/config.ts, especially parseInfo and loadFile, and compare the well-known source fallback policy described there. Then inspect packages/util/src/fs-util.ts and the atomic temp-file rename pattern in packages/core/src/git.ts. Define done as ensuring transient partial writes cannot make active sessions lose the last valid configuration; the issue describes atomic writes or last-good fallback as acceptable approaches.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Description
When any concurrent writer leaves a transient partial state in the live global config file (~/.config/opencode/opencode.jsonc), a reloading opencode process fails to parse it and rejects the WHOLE configuration document - there is no fallback to the last-good configuration. The provider catalog then loses every model, and each running session dies at its next step with SessionRunnerModel.ModelUnavailableError ("Failed to drain Session"). Observed live on v2.2.5 with several concurrent opencode serve --stdio / ACP clients: 11 "rejected malformed JSON or JSONC document" normalization warnings, each followed within seconds by session-drain failures across three server processes.
Two contributing factors verified at tag v2.2.5:
- Whole-document rejection without last-good fallback:
packages/core/src/config.ts(parseInfo/loadFile) drops the entry entirely when JSONC parsing fails. The codebase already follows the opposite policy for well-known sources - a failed refresh keeps the last resolved config "so remote providers and allowlists do not disappear" (config.ts, comment above the wellknown load path) - so extending that resilience to parse failures of the user's own config matches existing intent. - In-place write of the live config:
packages/core/src/config.tsline 482 persists viafs.writeWithDirs(filepath, ...), which resolves to a directfs.writeFileString(path, content)without a temp-file + rename swap (packages/util/src/fs-util.ts,writeWithDirs). The codebase already uses an atomic temp+rename pattern elsewhere (for examplepackages/core/src/git.tsaround line 967).
Reproduction notes: hammering PATCH /api/experimental/config 1200x against one server while another watched the same directory did NOT reproduce a partial read through opencode's own write path - its synchronous write completes before the watcher's next tick can observe intermediate bytes. However, any slower concurrent writer (editor autosave, scripts, plugin installs touching large configs) leaves the truncated-to-flushed window open long enough for readers to hit it, which matches how the live incidents occurred outside of controlled testing.
Expected behavior: readers of the live config never lose the entire configuration because of one transiently inconsistent state - either writes go through an atomic swap so partial states cannot be observed at all, or a parse failure falls back to the last-known-good document instead of dropping everything.
Plugins
none
OpenCode version
v2.2.5
Steps to reproduce
- Run two opencode server processes that watch the same global config directory.
- While sessions are active on both, have any third party rewrite the global config non-atomically and slowly enough that a reload lands inside the truncated-to-flushed window (editor-style save or chunked script write over a multi-kilobyte config).
- Observe "configuration normalization diagnostic ... rejected malformed JSON or JSONC document" in the log immediately followed by "Failed to drain Session" errors with
ModelUnavailableErroron all active sessions - no manual intervention recovers them until the file parses again.
Screenshot
n/a
Operating System
Ubuntu 24.04.5 LTS
Terminal
not applicable (ACP client)
Related Issues
- https://github.com/anomalyco/opencode/issues/16450 - plugin config files deleted when multiple opencode instances run concurrently; different mechanism (concurrent
bun installdeleting files), closed without a fix. This report covers whole-document rejection on partial reads, which kills running sessions instead of losing files.
- Lingua principale
- TypeScript
- Stelle
- 225k
- Fork
- 30.4k
- Merge medio
- 4h 16m
- PR unite (30g)
- 528
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di anomalyco/opencode
-
reproduced
Difficoltà 2/5 1-3 ore Idoneità per principianti 61/100
anomalyco/opencode#62873 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
anomalyco/opencode#62822 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
anomalyco/opencode#62601 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
reproduced
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
anomalyco/opencode#62516 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
anomalyco/opencode#62374 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di anomalyco/opencode
Issue simili
-
code-quality good-first-issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
OpenRailAssociation/netzgrafik-editor-frontend#1481 ·
I maintainer di solito rispondono entro 1 giorno
-
🙌 icon request
Difficoltà 2/5 1-3 ore Idoneità per principianti 63/100
lucide-icons/lucide#5183 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 81/100
cloudflare/capnweb#293 ·
I maintainer di solito rispondono entro 2 giorni
-
bug implicit-state
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
-
area:models enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno