Dispatcher Disposed Error
Trace Promise-backed dispatcher work requested after component teardown.What this error means and what can trigger it
DispatcherDisposedError means code called dispatcher.promise(...) or dispatcher.run(...) after the dispatcher had been disposed. Disposal sets the private flag, interrupts active fibers, clears dispatcher caches, and begins disposal of the managed runtime.
Usually, this comes from work retained past component teardown: a delayed task, external callback, stale event reference, or manual dispatcher reference outlives the component that owned it.
Other post-disposal operations have quieter fallbacks: fork(...) returns an inert disposer, while value(...) returns its fallback. This error is reserved for Promise-returning methods, since resolving one successfully would imply that new asynchronous work had actually started.
Exactly where it triggers
Promise bridge:
promise<A>(options: PromiseOptions<A>): Promise<A> {
if (this.#disposed) {
return Promise.reject(new DispatcherDisposedError());
}Direct effect run:
run<A, E, R>(effect: Effect.Effect<A, E, R>): Promise<A> {
if (this.#disposed) {
return Promise.reject(new DispatcherDisposedError());
}These methods do not throw synchronously. They return rejected Promises. Failing to await or otherwise observe the Promise can surface the class as an unhandled rejection. Disposal marks the flag at modules/svelte-effect-runtime/src/dispatcher/index.ts L385 @ C3.
Why this is the case
Both methods promise to bridge work through the dispatcher's managed runtime. After disposal, that runtime no longer has valid lifecycle ownership, and starting a fiber would detach it from component cleanup.
A rejected Promise still preserves each method's asynchronous contract and lets generated callers handle failure through their existing Promise path. The inert/fallback behavior of fork and value avoids creating new completion promises where their public contracts do not expose one.