A single malformed state.json in the temp dir takes the whole wmux window black — permanently, on every launch, until the file is removed. No crash dialog, process stays alive, only a restart "fixes" it (and then it happens again).
Hit this three times in a row on 0.23.0 running an orchestration.
Repro
Drop this in %TEMP%\wmux-orch-repro\state.json and start wmux:
{
"orchestrationId": "repro",
"task": "malformed run",
"status": "running",
"waves": [{ "index": 0, "status": "running", "agents": [] }]
}
Note orchestrationId where the schema wants id — a plausible typo, and exactly what an agent hand-rolling the file produced for me. Window goes black within a second.
Root cause
orchestration-watcher.ts reads state.json with a cast, not a check:
const parsed = JSON.parse(raw) as OrchestrationState; // no validation
parsed._orchDir = orchDir;
return parsed; // broadcast to renderer every 1s
state.json is written by a different process (the wmux-orchestrator plugin, or an agent), so it is untrusted input. The unvalidated object reaches OrchestrationPanel:
{orch.id.replace(/^orch-/, "")} // TypeError: Cannot read properties of undefined (reading "replace")
Two things turn that into a dead app:
- No error boundary anywhere in the renderer. React unmounts the entire tree on an uncaught render throw, leaving the window painted in its
#1a1a1a background — indistinguishable from a hang.
- The watcher prefers
status: "running". A stale/malformed running file therefore wins selection on every poll tick, so it re-crashes on every launch.
The console shows exactly one line, then nothing — because after the unmount there is nothing left to re-render and throw again:
INFO:CONSOLE "Uncaught TypeError: Cannot read properties of undefined (reading 'replace')"
Impact
Any process that can write %TEMP%\wmux-orch-*\state.json can hard-crash wmux. Worth noting scripts/orchestration-state.sh already carries trust-hardening comments (issue #2 / F-9) about not blindly following a running state.json — the watcher never got the same treatment.
Fix
PR incoming: validate id/status/waves in the watcher before broadcasting, add an ErrorBoundary (root + orchestration panel) so no single data-driven panel can blank the window again, and guard the panel itself. Includes a regression test for the malformed shapes.
A single malformed
state.jsonin the temp dir takes the whole wmux window black — permanently, on every launch, until the file is removed. No crash dialog, process stays alive, only a restart "fixes" it (and then it happens again).Hit this three times in a row on 0.23.0 running an orchestration.
Repro
Drop this in
%TEMP%\wmux-orch-repro\state.jsonand start wmux:{ "orchestrationId": "repro", "task": "malformed run", "status": "running", "waves": [{ "index": 0, "status": "running", "agents": [] }] }Note
orchestrationIdwhere the schema wantsid— a plausible typo, and exactly what an agent hand-rolling the file produced for me. Window goes black within a second.Root cause
orchestration-watcher.tsreads state.json with a cast, not a check:state.json is written by a different process (the wmux-orchestrator plugin, or an agent), so it is untrusted input. The unvalidated object reaches
OrchestrationPanel:Two things turn that into a dead app:
#1a1a1abackground — indistinguishable from a hang.status: "running". A stale/malformed running file therefore wins selection on every poll tick, so it re-crashes on every launch.The console shows exactly one line, then nothing — because after the unmount there is nothing left to re-render and throw again:
Impact
Any process that can write
%TEMP%\wmux-orch-*\state.jsoncan hard-crash wmux. Worth notingscripts/orchestration-state.shalready carries trust-hardening comments (issue #2 / F-9) about not blindly following arunningstate.json — the watcher never got the same treatment.Fix
PR incoming: validate
id/status/wavesin the watcher before broadcasting, add anErrorBoundary(root + orchestration panel) so no single data-driven panel can blank the window again, and guard the panel itself. Includes a regression test for the malformed shapes.