DeepSeek Harness host exits: inspector source is closed
You opened the experimental developer tools to inspect the plugin tree, and the host exited with a single line: dsh: fatal uncaught exception: Error: inspector: Host source is closed. The developer tools are not broken: the inspector source closes while a snapshot publish is still queued, the queued publish runs anyway, and setState throws on a closed source. The uncaught error then meets the host's fail-loud policy and becomes exit(1).
The crash signature in DeepSeek Harness: after closing, not opening
The crash usually arrives seconds after you close the developer tools or while the plugin tree is churning, and the log names inspector and publisher but no plugin. Check the pattern before changing anything:
- Open the tools normally — inspect the plugin tree for a few seconds; expected: no crash while the source is open.
- Close them and wait — leave DSH running for several seconds; expected: the process exits during this window.
- Read the trace — search the log for the faulting component; expected: inspector and publisher appear, with no plugin stack.
- Run without the tools — leave them closed for a long session; expected: no crash, which isolates the trigger.
According to the source review in the discussion, publisher.ts:31 throws from setState when the source is closed, while publish() at :24 only returns silently. The Cordis tree listener at src/shared/cordis/publisher.ts:22-23 does not check for closure, observers are only flagged in the disposer (observer.ts:27/31/40-44), and the throw escapes queueMicrotask(publish) with no catch (#10069). For other desktop diagnostics, see desktop debug configuration.
Reproduce the DSH inspector race in five beats
The ordering is the whole bug: closure happens first, the microtask runs second, and nothing between them asks whether the source is still alive. The sequence:
- Close the developer tools — the source enters the closed state, with no error yet.
- A publish is already queued — a tree change scheduled it as a microtask, and the task is still pending.
- The microtask runs — it walks the observers and calls
setStatewithout consulting the source state. setStatechecks the source — it finds closed and throws, so an inspector error surfaces.- Nothing catches it — fail-loud ends the process with
exit(1)and a minimal log line.
The more frequently the plugin tree changes, the more publishes are queued, and the more likely a close collides with one.
Three DeepSeek Harness fixes for the devtools crash
Bottom line: close in a safe order if you need the tools, turn off the experiment if you do not, and release observers when the source closes if you maintain a fork.
Containment 1: close in a safe order
Without code changes, the practical defence is to never close the tools while the plugin tree is still moving.
- Finish plugin operations first — stop installing, enabling or disabling plugins; expected: no new tree changes are generated.
- Wait for a stable list — confirm no row is pending or installing; expected: the queue has time to drain.
- Close the developer tools — do it only after that pause; expected: the source closes with no publish in flight.
- Do not quit immediately — give DSH a few seconds after closing; expected: any remaining microtasks finish before shutdown.
- Check the log — confirm no new publish was queued; expected: no inspector error follows.
Containment 2: turn off the experimental toggle
If you only opened the tools out of curiosity, disabling the experiment is the cheapest way to stop the crash.
- Open settings — go to experimental features and find the developer tools switch; expected: the toggle reflects its current state.
- Disable it and restart — relaunch DSH; expected: startup completes without an inspector error.
- Use the session normally — work for a while with the tools off; expected: no
inspector source closedappears. - Choose another diagnostic route — use logs and the
dshcommand line instead; expected: you keep observability without the experimental channel.
Root fix: release observers when the source closes
The correct repair is ownership: whoever holds the observers releases them on close, rather than teaching setState to swallow errors. Apply the changes in this order:
- Clear observers on close — in the inspector source's
close(), empty the observer list and mark pending publishes as cancelled; expected: no observer remains to receive a state change. - Guard publish by state — have
publish()return early when the source is closed; expected: late microtasks become no-ops. - Add context to the throw — include the source id and close reason; expected: the log identifies which channel failed.
- Wrap the microtask — add a catch around
queueMicrotask(publish)that logs instead of terminating; expected: a residual fault is recorded, not fatal. - Pin the regression — add a test that closes the source and immediately changes the tree; expected: the host survives.
| Change | Value | Priority |
|---|---|---|
| Release observers | Removes the cause | First |
| Check closed in publish | Cheap barrier for most races | Second |
| Richer setState error | Improves diagnosis | Third |
| Catch in the microtask | Last-resort safety net | Last, never alone |
Verify DSH fixes and avoid regressions
A fix is complete only when repeated open and close cycles, with tree changes in between, leave the host running. Verify with this sequence:
- Cycle the tools — open them and trigger three enable or disable actions; expected: no exit.
- Close and wait — hold for ten seconds; expected: the process stays alive.
- Reopen — reconnect the developer tools; expected: the inspector attaches again.
- Repeat five times — keep the tree changing between cycles; expected: no delayed crash or uncaught exception.
- Stress the publisher — use a plugin that updates state often, then close; expected: no further publish reaches a closed source.
Avoid these traps:
- Do not blanket-catch uncaught exceptions; that hides this crash and removes fail-loud protection from genuine ones.
- The developer tools are experimental, so confirm the fault still reproduces before patching.
- The exit can lag the close by seconds, so do not blame an unrelated DSH plugin for a random-looking shutdown.
- No official fix version is named; 0.2.1-rc.2 still reproduces, so check release notes after upgrading.
- Session data is usually safe because the crash happens in the inspector channel, but if it lands mid-write, open the most recent session once to confirm.
DeepSeek Harness inspector FAQ
Q: Why does DeepSeek Harness exit when I open the developer tools, with source is closed? A: DeepSeek Harness exits because of a race between closing the inspector source and publishing a snapshot. publisher.setState throws when the source is closed, the queueMicrotask has no catch, and the fail-loud policy turns the error into exit(1). Avoid closing the tools while the plugin tree is changing.
Q: Is the DeepSeek Harness inspector source closed error a plugin or core bug? A: The DeepSeek Harness inspector source closed error is a core lifecycle problem. Listeners on the Cordis tree are not unsubscribed when the source closes; observers are only flagged in the disposer. A publish can still be queued after the close, so setState throws; a plugin can trigger it but is not the root cause.
Q: Why does DeepSeek Harness exit instead of catching the error inside publish? A: DeepSeek Harness publish returns silently when the source is closed; the throw happens in setState, and the calling microtask has no catch. The host follows a fail-loud policy, so an uncaught exception ends the process; swallowing it would stop the crash but hide a lifecycle defect.
Q: How do I verify that DeepSeek Harness developer tools can be toggled repeatedly? A: DeepSeek Harness verification requires opening and closing the tools five times while the plugin tree changes between cycles. Check the log for inspector source closed or uncaught exception, then run a plugin that updates inspector state frequently and confirm there is no delayed crash.
FAQ
DeepSeek Harness exits because of a race between closing the inspector source and publishing a snapshot. publisher.setState throws when the source is closed, the queueMicrotask has no catch, and the fail-loud policy turns the error into exit(1). Avoid closing the tools while the plugin tree is changing.
The DeepSeek Harness inspector source closed error is a core lifecycle problem. Listeners on the Cordis tree are not unsubscribed when the source closes; observers are only flagged in the disposer. A publish can still be queued after the close, so setState throws; a plugin can trigger it but is not the root cause.
DeepSeek Harness publish returns silently when the source is closed; the throw happens in setState, and the calling microtask has no catch. The host follows a fail-loud policy, so an uncaught exception ends the process; swallowing it would stop the crash but hide a lifecycle defect.
DeepSeek Harness verification requires opening and closing the tools five times while the plugin tree changes between cycles. Check the log for inspector source closed or uncaught exception, then run a plugin that updates inspector state frequently and confirm there is no delayed crash.
Related Terms
- inspector
- inspector is the debug channel that exposes the plugin tree, services and runtime state. The developer tools read snapshots through it, and it has an explicit open and closed lifecycle.— https://github.com/deepseek-ai/deepseek-harness/discussions/10069
- publisher
- publisher is the inspector-side component that pushes state changes to observers. It tracks the source state and the subscription list; calling setState after the source closes throws.— https://github.com/deepseek-ai/deepseek-harness/discussions/10069
- fail-loud
- fail-loud is the host error policy: uncaught exceptions are logged and terminate the process instead of being swallowed. It turns a local inspector fault into a full host exit.— https://github.com/deepseek-ai/deepseek-harness/discussions/10069
Sources
- #10069 — Enabling the experimental developer tools lets a closed inspector source crash the host· deepseek-ai (GitHub Discussions)
- DeepSeek Harness source repository· deepseek-ai (GitHub)