quarkusio/quarkus · error · IllegalArgumentException

Pattern cannot be blank

Error message

Pattern cannot be blank

What it means

validatePatterns() also rejects blank pattern strings (empty or whitespace-only). A blank glob pattern is meaningless for PSUBSCRIBE and would either fail server-side or subscribe unexpectedly, so an IllegalArgumentException is thrown before the subscription request.

Source

Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactivePubSubCommandsImpl.java:122

            Consumer<Throwable> onException) {
        return subscribeToPatterns(List.of(pattern), onMessage, onEnd, onException);
    }

    @Override
    public Uni<ReactiveRedisSubscriber> subscribeToPattern(String pattern, BiConsumer<String, V> onMessage, Runnable onEnd,
            Consumer<Throwable> onException) {
        return subscribeToPatterns(List.of(pattern), onMessage, onEnd, onException);
    }

    private void validatePatterns(List<String> patterns) {
        notNullOrEmpty(patterns, "patterns");

        for (String pattern : patterns) {
            if (pattern == null) {
                throw new IllegalArgumentException("Pattern must not be null");
            }
            if (pattern.isBlank()) {
                throw new IllegalArgumentException("Pattern cannot be blank");
            }
        }
    }

    @Override
    public Uni<ReactiveRedisSubscriber> subscribeToPatterns(List<String> patterns, Consumer<V> onMessage, Runnable onEnd,
            Consumer<Throwable> onException) {
        nonNull(onMessage, "onMessage");
        validatePatterns(patterns);

        return RedisConnections.withNewLongLivedConnection(client, conn -> {
            RedisAPI api = RedisAPI.api(conn);
            ReactiveRedisPatternSubscriberImpl subscriber = new ReactiveRedisPatternSubscriberImpl(conn, api, patterns,
                    (channel, value) -> onMessage.accept(value), onEnd, onException);
            return subscriber.subscribe()
                    .replaceWith(subscriber);
        });
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Filter blank entries: patterns.stream().filter(p -> p != null && !p.isBlank()).toList().
  2. Trim user/config supplied patterns and drop empties before subscribing.
  3. Use a valid glob such as "*" or "channel.*" if a catch-all pattern is intended.

Example fix

// before
List<String> patterns = List.of(""); // blank
pubsub.subscribeToPatterns(patterns, onMessage);

// after
List<String> patterns = List.of("orders.*");
pubsub.subscribeToPatterns(patterns, onMessage);
Defensive patterns

Strategy: validation

Validate before calling

if (patterns == null || patterns.stream().anyMatch(p -> p == null || p.isBlank())) {
    throw new IllegalArgumentException("patterns must not contain blank entries");
}

Try / catch

try {
    pubsub.subscribeToPatterns(patterns, onMessage);
} catch (IllegalArgumentException e) {
    // trim/filter blanks and retry
}

Prevention

When it happens

Trigger: Calling subscribeToPatterns(...) with a list containing "" or " " (blank) elements.

Common situations: Empty configuration value parsed as an empty-string pattern; trimming bugs that leave whitespace-only strings; defaults like "" instead of omitting the pattern.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/2eeafd81c5df2b26. Report an issue: GitHub.