{"record":{"id":"d59f6c78a53546e2","repo":"flowable/flowable-engine","slug":"topicpattern-in-channel-model-channelmodel-m","errorCode":null,"errorMessage":"topicPattern in channel model [ <channelModel> ] must resolve to a Pattern or String, not <class>","messagePattern":"topicPattern in channel model \\[ <channelModel> \\] must resolve to a Pattern or String, not <class>","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java","lineNumber":575,"sourceCode":"                resolveTopics(object, result, channelDefinition);\n            }\n        } else {\n            throw new IllegalArgumentException(\n                \"Channel definition \" + channelDefinition + \" cannot resolve \" + resolvedValue + \" as a String[] or a String\");\n        }\n    }\n\n    protected Pattern resolvePattern(KafkaInboundChannelModel channelModel) {\n        Pattern pattern = null;\n        String topicPattern = channelModel.getTopicPattern();\n        if (StringUtils.hasText(topicPattern)) {\n            Object resolved = resolveExpression(topicPattern);\n            if (resolved instanceof String) {\n                pattern = Pattern.compile((String) resolved);\n            } else if (resolved instanceof Pattern) {\n                pattern = (Pattern) resolved;\n            } else if (resolved != null) {\n                throw new IllegalStateException(\n                    \"topicPattern in channel model [ \" + channelModel + \" ] must resolve to a Pattern or String, not \" + resolved.getClass());\n            }\n        }\n\n        return pattern;\n    }\n\n    protected Collection<TopicPartitionOffset> resolveTopicPartitions(KafkaInboundChannelModel channelModel) {\n        Collection<KafkaInboundChannelModel.TopicPartition> topicPartitions = channelModel.getTopicPartitions();\n        if (topicPartitions == null || topicPartitions.isEmpty()) {\n            return Collections.emptyList();\n        }\n\n        List<TopicPartitionOffset> tps = new ArrayList<>();\n        for (KafkaInboundChannelModel.TopicPartition topicPartition : topicPartitions) {\n            String topic = resolveExpressionAsString(topicPartition.getTopic(), \"topicPartitions[].topic\");\n            if (!StringUtils.hasText(topic)) {\n                throw new FlowableIllegalArgumentException(","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java#L557-L593","documentation":"resolvePattern resolves the topicPattern attribute of a Kafka inbound channel; the expression may resolve to a String (compiled via Pattern.compile) or a java.util.regex.Pattern, or null. Any other resolved type throws IllegalStateException. This guards regex-based topic subscription configuration.","triggerScenarios":"The channel's topicPattern attribute resolves (via expression/placeholder) to an object that is neither String, Pattern, nor null when createKafkaListenerEndpoint builds the listener.","commonSituations":"topicPattern points to a precompiled Pattern from a different regex library (e.g. scala.util.matching.Regex or Spring's PathPattern); a config property bound as a compiled object; expression returning a Character[].","solutions":["Configure topicPattern as a plain regex String, e.g. \"order-.*\".","If a Pattern object is intended, ensure it is java.util.regex.Pattern specifically.","Fix the placeholder to point at a string property, not an object.","Validate the regex compiles (also avoids PatternSyntaxException downstream)."],"exampleFix":"// before\ntopicPattern: ${compiledPatternBean}   // not java.util.regex.Pattern\n\n// after\ntopicPattern: \"order-.*\"","handlingStrategy":"type-guard","validationCode":"Object resolved = resolveExpression(topicPattern);\nif (resolved != null && !(resolved instanceof String) && !(resolved instanceof java.util.regex.Pattern))\n    throw new IllegalArgumentException(\"topicPattern must be a String or java.util.regex.Pattern\");","typeGuard":"boolean isPatternLike(Object v) { return v == null || v instanceof String || v instanceof java.util.regex.Pattern; }","tryCatchPattern":"try { ... } catch (IllegalStateException e) { if (e.getMessage().contains(\"must resolve to a Pattern or String\")) { log.error(\"topicPattern wrong type: {}\", e.getMessage()); } else throw e; }","preventionTips":["Configure topicPattern as a regex String","If passing Pattern objects, ensure they are java.util.regex.Pattern","Compile-check the regex in unit tests"],"tags":["kafka","type-mismatch","regex","expression-resolution"],"backgroundTag":"type-mismatch","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}