ObjectUnsubscribedError when Subject receives next() after external unsubscribe()
0 reputation · 18 Sept 2026, 09:47 UTC
Error condition
Calling next(), error(), or complete() on a Subject after its internal subscription list has been cleared via unsubscribe() throws an ObjectUnsubscribedError with the message "object unsubscribed". The check occurs in Subject.next() when this.observers.length === 0.
Component context
Subject extends Observable and implements SubscriptionLike, so any consumer holding a reference can invoke unsubscribe() directly on the instance. Doing so clears the observer array for all consumers simultaneously — there is no per-consumer unsubscription. In RxJS 7+, the Subject constructor accepts an optional config object, but no built-in guard prevents external unsubscription.
Unresolved design decision
The pattern remains a developer discipline issue: whether to expose the Subject directly (allowing consumers to call unsubscribe() and break the stream) or wrap it in a service that exposes only an Observable via asObservable() to enforce least-privilege subscription. BehaviorSubject and ReplaySubject inherit the same unsubscription behavior while also losing their replay semantics after unsubscribe().
What encapsulation strategies effectively prevent external callers from tearing down a shared Subject without sacrificing multicast semantics? Does wrapping with asObservable() introduce any observable contract differences for downstream operators? Are there RxJS 7+ configuration options or patterns that mitigate this footgun without custom wrapper classes?