{"record":{"id":"fdc2e3865b1af3c2","repo":"quarkusio/quarkus","slug":"channel-must-not-be-null","errorCode":null,"errorMessage":"Channel must not be null","messagePattern":"Channel must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactivePubSubCommandsImpl.java","lineNumber":163,"sourceCode":"            Consumer<Throwable> onException) {\n        validatePatterns(patterns);\n        nonNull(onMessage, \"onMessage\");\n\n        return RedisConnections.withNewLongLivedConnection(client, conn -> {\n            RedisAPI api = RedisAPI.api(conn);\n            ReactiveRedisPatternSubscriberImpl subscriber = new ReactiveRedisPatternSubscriberImpl(conn, api, patterns,\n                    onMessage, onEnd, onException);\n            return subscriber.subscribe()\n                    .replaceWith(subscriber);\n        });\n    }\n\n    private void validateChannels(List<String> channels) {\n        notNullOrEmpty(channels, \"channels\");\n\n        for (String pattern : channels) {\n            if (pattern == null) {\n                throw new IllegalArgumentException(\"Channel must not be null\");\n            }\n            if (pattern.isBlank()) {\n                throw new IllegalArgumentException(\"Channel cannot be blank\");\n            }\n        }\n    }\n\n    @Override\n    public Uni<ReactiveRedisSubscriber> subscribe(List<String> channels, Consumer<V> onMessage, Runnable onEnd,\n            Consumer<Throwable> onException) {\n        nonNull(onMessage, \"onMessage\");\n        validateChannels(channels);\n\n        return RedisConnections.withNewLongLivedConnection(client, conn -> {\n            RedisAPI api = RedisAPI.api(conn);\n            ReactiveAbstractRedisSubscriberImpl subscriber = new ReactiveAbstractRedisSubscriberImpl(conn, api,\n                    channels, (channel, value) -> onMessage.accept(value), onEnd, onException);\n            return subscriber.subscribe()","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactivePubSubCommandsImpl.java#L145-L181","documentation":"validateChannels() pre-checks the channel list for plain (non-pattern) subscriptions. A null channel element is invalid for Redis SUBSCRIBE, so an IllegalArgumentException is thrown before contacting the server. The list itself must also be non-null/non-empty (notNullOrEmpty check).","triggerScenarios":"Calling subscribe(...) with a List<String> of channels containing a null element.","commonSituations":"Channel names built from nullable variables or optional config values; collecting channels from a map/collection that permits null values.","solutions":["Filter null (and blank) entries before subscribing: channels.stream().filter(Objects::nonNull).toList().","Validate channel names when assembling the subscription list.","Ensure the channel list is non-empty; skip subscription entirely if there is nothing to subscribe to."],"exampleFix":"// before\nsubscriber = pubsub.subscribe(channels, onMessage);\n\n// after\nList<String> safe = channels.stream().filter(c -> c != null && !c.isBlank()).toList();\nsubscriber = pubsub.subscribe(safe, onMessage);","handlingStrategy":"validation","validationCode":"if (channels == null || channels.isEmpty() || channels.stream().anyMatch(Objects::isNull)) {\n    throw new IllegalArgumentException(\"channels must be non-empty with no null elements\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    pubsub.subscribe(channels, onMessage);\n} catch (IllegalArgumentException e) {\n    // sanitize channel list and retry\n}","preventionTips":["Build channel lists from non-nullable sources or filter first.","Skip subscription when the resolved channel list is empty.","Centralize channel name constants to avoid null leakage."],"tags":["redis","quarkus","pubsub","argument-validation"],"backgroundTag":"invalid-argument-null","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"}