ReactiveX/RxJava · error · IllegalArgumentException
unsafeCreate(Single) should be upgraded
Error message
unsafeCreate(Single) should be upgraded
What it means
Thrown by Single.unsafeCreate when the argument is already a Single instance. unsafeCreate exists to bridge foreign SingleSource implementations; wrapping a real Single is redundant, likely a port remnant, and the docs suggest using hide() if you genuinely need to obscure identity. The NPE check runs before this guard, so a null source throws NPE first.
Source
Thrown at src/main/java/io/reactivex/rxjava4/core/Single.java:1383
* <dt><b>Scheduler:</b></dt>
* <dd>{@code unsafeCreate} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the value type
* @param onSubscribe the function that is called with the subscribing {@code SingleObserver}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code onSubscribe} is {@code null}
* @throws IllegalArgumentException if {@code source} is a subclass of {@code Single}; such
* instances don't need conversion and is possibly a port remnant from 1.x or one should use {@link #hide()}
* instead.
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single<T> unsafeCreate(@NonNull SingleSource<T> onSubscribe) {
Objects.requireNonNull(onSubscribe, "onSubscribe is null");
if (onSubscribe instanceof Single) {
throw new IllegalArgumentException("unsafeCreate(Single) should be upgraded");
}
return RxJavaPlugins.onAssembly(new SingleFromUnsafeSource<>(onSubscribe));
}
/**
* Allows using and disposing a resource while running a {@link SingleSource} instance generated from
* that resource (similar to a try-with-resources).
* <p>
* <img width="640" height="380" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.using.v3.png" alt="">
* <dl>
* <dt><b>Scheduler:</b></dt>
* <dd>{@code using} does not operate by default on a particular {@link Scheduler}.</dd>
* </dl>
* @param <T> the value type of the {@code SingleSource} generated
* @param <U> the resource type
* @param resourceSupplier the {@link Supplier} called for each {@link SingleObserver} to generate a resource object
* @param sourceSupplier the function called with the returned resource
* object from {@code resourceSupplier} and should return a {@code SingleSource} instanceView on GitHub (pinned to a8ab535614)
Solutions
- Use the Single directly instead of wrapping: drop the unsafeCreate call.
- If you need to hide identity, call source.hide().
- Restrict the call site so unsafeCreate only receives non-Single SingleSource instances.
Example fix
// before Single<String> src = loadSingle(); Single<String> wrapped = Single.unsafeCreate(src); // after Single<String> wrapped = src; // or, to hide identity: Single<String> hidden = src.hide();
Defensive patterns
Strategy: type-guard
Validate before calling
SingleSource<T> source = loadSource();
if (source instanceof Single) {
// unsafeCreate would throw; use directly or hide()
return;
} Type guard
static <T> boolean needsUnsafeCreate(SingleSource<T> s) {
return s != null && !(s instanceof Single);
} Try / catch
try {
return Single.unsafeCreate(source);
} catch (IllegalArgumentException e) {
return source instanceof Single ? (Single<T>) source : Single.error(e);
} Prevention
- Use unsafeCreate only for foreign SingleSource implementations, not for Single.
- Prefer hide() when you need to obscure Single identity.
- Type-guard generic adapters that accept SingleSource.
When it happens
Trigger: Calling Single.unsafeCreate(someSingle) where the runtime type is Single. Common when an upstream helper returns Single and the caller wraps it unconditionally.
Common situations: RxJava 1.x-to-3.x/4.x migration; generic adapters that wrap any source without checking its concrete type.
Related errors
- Use of unsafeCreate(Completable)!
- unsafeCreate(Maybe) should be upgraded
- count >= 0 required but it was {}
- count >= 0 required but it was {}
- count >= 0 required but it was {}
AI-assisted analysis of ReactiveX/RxJava@a8ab535614 (2026-08-13).
Data as JSON: /api/errors/7f1e2d2c4d2b43c4.
Report an issue: GitHub.