lysine-dev/retrofit · error · NullPointerException

scheduler == null

Error message

scheduler == null

What it means

RxJava2CallAdapterFactory.createWithScheduler(Scheduler) builds an adapter factory that subscribeOn's the supplied scheduler by default. Passing null is rejected because the factory would then hold no scheduler to apply; for the no-scheduler case the library provides dedicated factory methods (create() for synchronous, createAsync() for asynchronous). It throws NullPointerException ('scheduler == null') behind a ConstantConditions suppression.

Source

Thrown at retrofit-adapters/rxjava2/src/main/java/retrofit2/adapter/rxjava2/RxJava2CallAdapterFactory.java:81

   * Returns an instance which creates synchronous observables that do not operate on any scheduler
   * by default.
   */
  public static RxJava2CallAdapterFactory create() {
    return new RxJava2CallAdapterFactory(null, false);
  }

  /** Returns an instance which creates asynchronous observables. */
  public static RxJava2CallAdapterFactory createAsync() {
    return new RxJava2CallAdapterFactory(null, true);
  }

  /**
   * Returns an instance which creates synchronous observables that {@linkplain
   * Observable#subscribeOn(Scheduler) subscribe on} {@code scheduler} by default.
   */
  @SuppressWarnings("ConstantConditions") // Guarding public API nullability.
  public static RxJava2CallAdapterFactory createWithScheduler(Scheduler scheduler) {
    if (scheduler == null) throw new NullPointerException("scheduler == null");
    return new RxJava2CallAdapterFactory(scheduler, false);
  }

  private final @Nullable Scheduler scheduler;
  private final boolean isAsync;

  private RxJava2CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
    this.scheduler = scheduler;
    this.isAsync = isAsync;
  }

  @Override
  public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    Class<?> rawType = getRawType(returnType);

    if (rawType == Completable.class) {
      // Completable is not parameterized (which is what the rest of this method deals with) so it

View on GitHub (pinned to d0b112dad0)

Solutions

  1. If you want no custom scheduler, use the dedicated factory: RxJava2CallAdapterFactory.create()() or RxJava2CallAdapterFactory.createAsync().
  2. Otherwise supply a real Scheduler such as Schedulers.io(), Schedulers.computation(), or AndroidSchedulers.mainThread().
  3. Resolve the null at its source (DI binding / config property) rather than passing it through.

Example fix

// before
RxJavaCallAdapterFactory factory = RxJava2CallAdapterFactory.createWithScheduler(configScheduler);
// after
RxJava2CallAdapterFactory factory = configScheduler != null
    ? RxJava2CallAdapterFactory.createWithScheduler(configScheduler)
    : RxJava2CallAdapterFactory.createAsync();
Defensive patterns

Strategy: validation

Validate before calling

Scheduler s = resolveScheduler(); // may be null when unconfigured
RxJava2CallAdapterFactory factory =
    s != null
      ? RxJava2CallAdapterFactory.createWithScheduler(s)
      : RxJava2CallAdapterFactory.createAsync();

Try / catch

try {
  factory = RxJava2CallAdapterFactory.createWithScheduler(s);
} catch (NullPointerException e) {
  // s was null; fall back to the async factory
  factory = RxJava2CallAdapterFactory.createAsync();
}

Prevention

When it happens

Trigger: Calling RxJava2CallAdapterFactory.createWithScheduler(null), most often when the scheduler is read from DI/configuration/env that was not bound and resolved to null. Thrown immediately at the top of createWithScheduler.

Common situations: Reading a Scheduler from a DI graph or config property that resolved to null; conditional scheduler selection that falls through to null; copy-paste of createWithScheduler without choosing the right base factory method; environment differences (e.g. Android main thread scheduler absent in unit tests).

Related errors


AI-assisted analysis of lysine-dev/retrofit@d0b112dad0 (2026-08-13). Data as JSON: /api/errors/698bb097bfa30aa1. Report an issue: GitHub.