ReactiveX/rxjs · error · TypeError

Unexpected notification kind ${kind}

Error message

Unexpected notification kind ${kind}

What it means

Notification.toObservable() validates that the notification's kind is one of 'N', 'E', 'C' before building an Observable. A notification object with any other kind (or a mutated/custom kind) is not a valid ObservableNotification and throws a TypeError.

Source

Thrown at packages/rxjs/src/notification.ts:63

    } else {
      complete?.();
    }
  }

  accept(observer: Partial<Observer<T>>): void;
  accept(next: (value: T) => void, error?: (error: any) => void, complete?: () => void): void;
  accept(nextOrObserver: Partial<Observer<T>> | ((value: T) => void), error?: (error: any) => void, complete?: () => void): void {
    if (typeof nextOrObserver === 'object' && nextOrObserver !== null) {
      this.observe(nextOrObserver);
    } else {
      this.do(nextOrObserver, error, complete);
    }
  }

  toObservable(): Observable<T> {
    const { kind, value, error } = this;
    if (kind !== 'N' && kind !== 'E' && kind !== 'C') {
      throw new TypeError(`Unexpected notification kind ${kind}`);
    }

    return new Observable<T>((subscriber) => {
      if (kind === 'N') {
        subscriber.next(value as T);
        subscriber.complete();
      } else if (kind === 'E') {
        subscriber.error(error);
      } else {
        subscriber.complete();
      }
    });
  }

  private static readonly completeNotification = new Notification('C') as Notification<never> & CompleteNotification;

  static createNext<T>(value: T): Notification<T> & NextNotification<T> {
    return new Notification('N', value) as Notification<T> & NextNotification<T>;

View on GitHub (pinned to 54796b38a5)

Solutions

  1. Normalize kinds to uppercase 'N'/'E'/'C' before calling toObservable
  2. Use the factory helpers nextNotification(), errorNotification(), completeNotification() instead of constructing Notification manually
  3. Add a type guard on kind before conversion

Example fix

// before
const n = JSON.parse(json); // {kind: 'n', value: 1}
n.toObservable?.(); // throws
// after
const n = JSON.parse(json);
if (n.kind) n.kind = n.kind.toUpperCase();
Notification.prototype.toObservable.call(n);
Defensive patterns

Strategy: type-guard

Validate before calling

const kind = notification.kind;
if (kind !== 'N' && kind !== 'E' && kind !== 'C') throw new TypeError('bad kind');
notification.toObservable();

Type guard

function isValidNotification(n: { kind?: unknown }): n is ObservableNotification<any> {
  return n.kind === 'N' || n.kind === 'E' || n.kind === 'C';
}

Prevention

When it happens

Trigger: new Notification('X' as any, value).toObservable(), or calling toObservable() on a hand-rolled object {kind: 'n', value} (lowercase kind from a serialization round-trip).

Common situations: Notifications deserialized from JSON where the kind casing was lost, or third-party code constructing Notification-like objects with non-standard kinds.

Related errors


AI-assisted analysis of ReactiveX/rxjs@54796b38a5 (2026-08-28). Data as JSON: /api/errors/9bca94edb6880da5. Report an issue: GitHub.