Skip to content

You provided an invalid object where a stream was expected error in Module Federation environment #6628

Open
@dragonflypl

Description

@dragonflypl

Bug Report

Current Behavior

switchMap (and other mapping operators) might not work correctly in Module Federation environment.

Code like:

this
  .getSomeObservable()
  .pipe(
    switchMap(() => this.getOtherObservable()) // switching here causes the error
  ).subscribe()

Will cause : You provided an invalid object where a stream was expected error in Module Federation environment exception

Expected behavior

Mapping operators should work and recognise

Reproduction

I was not able yet to reproduce it with a repo I could publicly push. This is explanation from the app I'm maintaining.

I've migrated one app to MFE Architecture using Module Federation and mysteriously looking error is thrown at runtime:

You provided an invalid object where a stream was expected error. You can provide an Observable, Promise, Array, or Iterable.

The code that causes it looks like this:

this
  .getSomeObservable()
  .pipe(
    switchMap(() => this.getOtherObservable()) // switching here causes the error
  ).subscribe()

However I was pretty sure code was ok...

When analysing stack trace, error originates from:

https://github.com/ReactiveX/rxjs/blob/6.6.7/src/internal/util/subscribeTo.ts

export const subscribeTo = <T>(result: ObservableInput<T>): (subscriber: Subscriber<T>) => Subscription | void => {
  if (!!result && typeof result[Symbol_observable] === 'function') {
    return subscribeToObservable(result as any);
  } else if (isArrayLike(result)) {
    return subscribeToArray(result);
  } else if (isPromise(result)) {
    return subscribeToPromise(result as Promise<any>);
  } else if (!!result && typeof result[Symbol_iterator] === 'function') {
    return subscribeToIterable(result as any);
  } else {
    const value = isObject(result) ? 'an invalid object' : `'${result}'`;
    const msg = `You provided ${value} where a stream was expected.`
      + ' You can provide an Observable, Promise, Array, or Iterable.';
    throw new TypeError(msg);
  }
};

In my case, result is of type BehaviorSubject.

However, when I compared stack trace when app is running in non-federated to federated, the issue is here:

https://github.com/ReactiveX/rxjs/blob/6.6.7/src/internal/innerSubscribe.ts#L110

  if (result instanceof Observable) {
    return result.subscribe(innerSubscriber);
  }

Without module federation, this if is truthy, when I look at prototypes, deeper I can find Observable.

However in federated environment, this expression is falsy.

The good news it that refactoring to:

this
  .getSomeObservable()
  .subscribe(() => this.getOtherObservable().subscribe())

does not throw error any more.

Environment

  • RxJS version: 6.6.7
  • Build configuration: webpack@5.50.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions