{"record":{"id":"e8f59f86f1fffcba","repo":"quarkusio/quarkus","slug":"the-subscriber-must-not-be-null","errorCode":null,"errorMessage":"The subscriber must not be `null`","messagePattern":"The subscriber must not be `null`","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/RestMulti.java","lineNumber":201,"sourceCode":"        private final AtomicReference<Map<String, List<String>>> headers;\n        private final Uni<I> upstream;\n\n        public <T> AsyncRestMulti(Uni<I> upstream,\n                Function<? super I, ? extends Multi<? extends O>> dataExtractor,\n                Function<I, Map<String, List<String>>> headersExtractor,\n                Function<I, Integer> statusExtractor) {\n            this.upstream = upstream;\n            this.dataExtractor = dataExtractor;\n            this.statusExtractor = statusExtractor;\n            this.headersExtractor = headersExtractor;\n            this.status = new AtomicReference<>(null);\n            this.headers = new AtomicReference<>(Collections.emptyMap());\n        }\n\n        @Override\n        public void subscribe(MultiSubscriber<? super O> subscriber) {\n            if (subscriber == null) {\n                throw new NullPointerException(\"The subscriber must not be `null`\");\n            }\n            AbstractUni.subscribe(upstream, new FlatMapPublisherSubscriber<>(subscriber, dataExtractor, statusExtractor, status,\n                    headersExtractor, headers));\n        }\n\n        @Override\n        public Integer getStatus() {\n            return status.get();\n        }\n\n        @Override\n        public Map<String, List<String>> getHeaders() {\n            return headers.get();\n        }\n\n        static final class FlatMapPublisherSubscriber<I, O>\n                implements Flow.Subscriber<O>, UniSubscriber<I>, Flow.Subscription, ContextSupport {\n","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/RestMulti.java#L183-L219","documentation":"RestMulti implements MultiSubscriber semantics and follows the reactive-streams spec rule 2.13: subscribing with a null subscriber is a hard error. subscribe() throws NullPointerException when passed null, preventing NPEs deeper inside the reactive pipeline.","triggerScenarios":"Calling `restMulti.subscribe(null)` directly, or framework plumbing (e.g. AbstractUni.subscribe wiring) passing a null subscriber because a downstream stage was never initialized.","commonSituations":"Custom integration code that resolves the subscriber from an optional context/parameter and passes the null result through; misordered initialization in custom reactive adapters.","solutions":["Ensure a non-null MultiSubscriber is passed; construct a default/logging subscriber when none is available.","Check the upstream caller that produced a null subscriber (uninitialized field, failed injection) and fix its initialization.","Let Mutiny's built-in subscription APIs (e.g. `multi.subscribe().with(...)` with non-null callbacks) handle subscription instead of calling subscribe(null) directly."],"exampleFix":"// before\nMultiSubscriber<? super Item> sub = resolveSubscriber(); // may be null\nrestMulti.subscribe(sub);\n// after\nMultiSubscriber<? super Item> sub = resolveSubscriber();\nif (sub == null) {\n    sub = new LoggingSubscriber<>();\n}\nrestMulti.subscribe(sub);","handlingStrategy":"type-guard","validationCode":"if (subscriber == null) {\n    subscriber = new LoggingSubscriber<>();\n}\nrestMulti.subscribe(subscriber);","typeGuard":"boolean hasSubscriber(MultiSubscriber<?> s) {\n    return s != null;\n}","tryCatchPattern":"try {\n    restMulti.subscribe(subscriber);\n} catch (NullPointerException e) {\n    LOG.error(\"Attempted to subscribe with null subscriber\", e);\n}","preventionTips":["Prefer Mutiny's subscribe().with(consumer) APIs, which never accept null subscribers silently.","Initialize subscriber fields eagerly; make resolveSubscriber() return a default instead of null.","Follow reactive-streams spec rule 2.13 in any custom reactive adapter code."],"tags":["null-pointer","reactive-streams","resteasy-reactive","subscription"],"backgroundTag":"null-subscriber","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}