{"record":{"id":"bb603c2acbe9eb51","repo":"ReactiveX/RxJava","slug":"use-of-unsafecreate-completable","errorCode":null,"errorMessage":"Use of unsafeCreate(Completable)!","messagePattern":"Use of unsafeCreate\\(Completable\\)!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/reactivex/rxjava4/core/Completable.java","lineNumber":427,"sourceCode":"     * <p>\n     * <img width=\"640\" height=\"260\" src=\"https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Completable.unsafeCreate.png\" alt=\"\">\n     * <dl>\n     *  <dt><b>Scheduler:</b></dt>\n     *  <dd>{@code unsafeCreate} does not operate by default on a particular {@link Scheduler}.</dd>\n     * </dl>\n     * @param onSubscribe the callback which will receive the {@link CompletableObserver} instances\n     * when the {@code Completable} is subscribed to.\n     * @return the new {@code Completable} instance\n     * @throws NullPointerException if {@code onSubscribe} is {@code null}\n     * @throws IllegalArgumentException if {@code source} is a {@code Completable}\n     */\n    @CheckReturnValue\n    @NonNull\n    @SchedulerSupport(SchedulerSupport.NONE)\n    public static Completable unsafeCreate(@NonNull CompletableSource onSubscribe) {\n        Objects.requireNonNull(onSubscribe, \"onSubscribe is null\");\n        if (onSubscribe instanceof Completable) {\n            throw new IllegalArgumentException(\"Use of unsafeCreate(Completable)!\");\n        }\n        return RxJavaPlugins.onAssembly(new CompletableFromUnsafeSource(onSubscribe));\n    }\n\n    /**\n     * Defers the subscription to a {@code Completable} instance returned by a supplier.\n     * <p>\n     * <img width=\"640\" height=\"298\" src=\"https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Completable.defer.png\" alt=\"\">\n     * <dl>\n     *  <dt><b>Scheduler:</b></dt>\n     *  <dd>{@code defer} does not operate by default on a particular {@link Scheduler}.</dd>\n     * </dl>\n     * @param supplier the supplier that returns the {@code Completable} that will be subscribed to.\n     * @return the new {@code Completable} instance\n     * @throws NullPointerException if {@code supplier} is {@code null}\n     */\n    @CheckReturnValue\n    @NonNull","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/ReactiveX/RxJava/blob/a8ab5356143f37a8f1dd6d76c79191bec5fa343b/src/main/java/io/reactivex/rxjava4/core/Completable.java#L409-L445","documentation":"Thrown by Completable.unsafeCreate when the passed source is already a Completable instance. unsafeCreate exists to bridge foreign CompletableSource implementations; wrapping a real Completable is redundant (you already have the target type) and is almost always a 1.x-to-3.x/4.x porting remnant. The guard is an explicit instanceof check that fails fast at assembly time.","triggerScenarios":"Calling Completable.unsafeCreate(someCompletable) where the argument's runtime type is Completable (not just CompletableSource). Common when a method returns Completable and the caller passes it straight into unsafeCreate.","commonSituations":"Migrating RxJava 1.x code that used Observable.unsafeCreate patterns; helper utilities that accept a generic source and unconditionally wrap it; generated/builder code that blindly calls unsafeCreate on whatever upstream it receives.","solutions":["Pass the Completable through unchanged instead of wrapping it: drop the unsafeCreate call.","If you need to hide the concrete identity (so downstream sees a fresh CompletableSource), call source.hide() instead of unsafeCreate(source).","If the argument may legitimately be a foreign CompletableSource, narrow the call site so unsafeCreate only receives non-Completable sources."],"exampleFix":"// before\nCompletable src = loadCompletable();\nCompletable wrapped = Completable.unsafeCreate(src);\n\n// after\nCompletable wrapped = src;\n// or, to hide identity:\nCompletable hidden = src.hide();","handlingStrategy":"type-guard","validationCode":"CompletableSource source = loadSource();\nif (source instanceof Completable) {\n    // unsafeCreate would throw; use directly or hide()\n    return;\n}","typeGuard":"static boolean needsUnsafeCreate(CompletableSource s) {\n    return s != null && !(s instanceof Completable);\n}","tryCatchPattern":"try {\n    return Completable.unsafeCreate(source);\n} catch (IllegalArgumentException e) {\n    // source was already a Completable; use it directly\n    return source instanceof Completable ? (Completable) source : Completable.error(e);\n}","preventionTips":["Treat unsafeCreate as a bridge for foreign sources only, never for your own Completable.","Prefer hide() when you need to obscure the concrete Completable identity.","Add a static type guard in helper code that accepts CompletableSource generically."],"tags":["rxjava","completable","unsafe-create","api-misuse","argument-validation"],"backgroundTag":null,"analyzedSha":"a8ab5356143f37a8f1dd6d76c79191bec5fa343b","analyzedAt":"2026-08-13T23:25:30.069Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}