OpenCode agents crash on spawn ("CRASHED · exit 1") — the TUI has no --model flag, so every model pick is a kill switch

Aperta
#703 1 commento 2 reazioni 0 assegnatari Vedi su GitHub

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
65/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
electron, typescript
Ambito
desktop

Direzione di ricerca

Start with the OpenCode preset in src/shared/agentProvider.ts, then trace model handling through src/main/workerLaunch.ts and src/main/index.ts; compare with src/renderer/src/store/config.ts and src/main/config.ts. Run the relevant unit tests for the preset contract, buildWorkerLaunch, and slug validation. Done means selected OpenCode models reach the TUI through config, invalid stored models fall back to CLI default, and BYOK keys remain scoped.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

What happened?

Every OpenCode agent dies on spawn with exit 1 and the floor card reads CRASHED · exit 1. The CLI is refusing the command line we build for it:

$ opencode --model claude-opus-5-5
ERROR
  Unrecognized flag: --model in command opencode

--model is a flag of opencode run (the headless one-shot), not of the interactive TUI this app spawns. OpenCode prints its usage screen and exits 1, so an agent with a model selected can never start — the model picker is effectively a kill switch.

This hits two spawn paths, both of which append the model flag from the preset's modelFlag: '--model':

  • the renderer path (buildSpawnCommand) — every god respawn and every GUI hire;
  • the main-only worker path (buildWorkerLaunch) — god-hired ephemeral workers.

Expected: an OpenCode agent with a model selected starts and runs on that model; one without a selection starts on OpenCode's own default.

Steps to reproduce

  1. Launch the app with an OpenCode agent on the floor (Command Center → Engine: OpenCode), and pick any model other than CLI default — e.g. anthropic/claude-sonnet-4-5.
  2. Apply, or simply wait for the hourly ops standup mission to respawn the god.
  3. The agent card flips to CRASHED · exit 1 within about a second.
  4. Confirm against the CLI: opencode --model <anything> exits 1 with Unrecognized flag: --model.

The bare-id case is a second layer of the same bug and does not even need a wrong pick: a config that pairs godProvider: "opencode" with a leftover Claude-era godModel (e.g. claude-opus-5-5, which is what a config written before the engine was switched carries) puts a bare Claude id where OpenCode needs a provider/model slug, so even the config-delivered model resolves to nothing.

Screenshot or screen recording

The floor card reading CRASHED · exit 1 on the god, with the crash log tail quoted below.

Logs / stack trace

~/.config/munder-difflin/crashes/2026-10-06T15-33-44-121Z-god.log:

agent:    god
exitCode: 1
command:  /home/can/.npm-global/bin/opencode
--- last 2837 bytes of pty output ---
...
ERROR
  Unrecognized flag: --model in command opencode

hive/log.jsonl records the same pair on every respawn:

{"kind":"spawn","agentId":"god","name":"Ahmet","isGod":true}
{"kind":"agent-exit","agentId":"god","exitCode":1,"signal":0,"abnormal":true,
 "tailPath":".../crashes/2026-10-06T15-33-44-121Z-god.log"}

Root cause

AgentProviderPreset had no way to say "this CLI has a model picker but no model flag", so the OpenCode preset claimed modelFlag: '--model' — the one flag that CLI rejects on the command we spawn. Three sites then trusted supportsModel/modelFlag and put it on argv:

  • src/renderer/src/store/config.ts — buildSpawnCommand
  • src/main/workerLaunch.ts — buildWorkerLaunch
  • src/main/index.ts — the BYOK block, which additionally read the model slug back out of argv to scope key injection

That last one is worth calling out separately: with no --model on argv, prefix resolved empty and the block fell through to handing every stored BYOK key to the CLI, quietly voiding the least-privilege guardrail it implements (Pam/Jim NIT-2).

A note on the preset's existing recommendedOrchestratorModel: undefined: the intent recorded there was right — don't presume a model for the user. It just had no mechanism for the other half, honouring a model when the user did pick one.

Fix

  • src/shared/agentProvider.ts — OpenCode's modelFlag is now undefined and a new modelViaConfig: true marks the config-file route. Added modelFlagForProvider(), deliversModelViaConfig() and isProviderScopedModel() so every model-appending site consults the flag's real existence rather than supportsModel, plus a validator for the provider/model slug form.
  • src/renderer/src/store/config.ts — unchanged behaviour (the preset.modelFlag gate was already correct); the trap is now documented at the site.
  • src/main/workerLaunch.ts — the model only goes on argv when the preset has a flag. The effective model is returned on WorkerLaunch.model either way, so a pick still reaches an engine that wants it via config.
  • src/main/index.ts — the model is delivered to OpenCode through OPENCODE_CONFIG_CONTENT (model), which is where its TUI reads it; the BYOK prefix now resolves from the role model too, restoring least-privilege scoping; the local/<id> base-URL registration works again for the same reason.
  • src/main/config.ts — readConfig drops a godModel that cannot be valid for a config-delivered engine (dropUnusableGodModel), so an already-broken config lands on CLI default and boots instead of needing the user to find the one dropdown that fixes it.

Verification

  • tsc --noEmit on both tsconfig.node.json and tsconfig.web.json: error sets byte-identical before and after the change (remaining errors are pre-existing, from node-pty / electron-updater being absent in the environment used to check).
  • Unit tests added for the preset contract, buildWorkerLaunch and the slug validator.

Environment

  • Operating system: Linux — Ubuntu 26.04.1 LTS
  • OS version: Ubuntu 26.04.1
  • Munder Difflin version: 0.5.5 (packaged AppImage)
  • Node version: v24.19.0
  • Agent CLI and version: opencode v2.0.24 (npm @opencode/cli), Linux x86_64
Lingua principale
TypeScript
Stelle
8.5k
Fork
1.2k
Merge medio
14h 49m
PR unite (30g)
55

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di HarnessMD/munder-difflin

Tutte le issue di HarnessMD/munder-difflin

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.