{"record":{"id":"54c305ad21ed5c86","repo":"flowable/flowable-engine","slug":"only-one-of-topics-topicpartitions-or-topicpatter","errorCode":null,"errorMessage":"Only one of topics, topicPartitions or topicPattern must are allowed for <endpoint>","messagePattern":"Only one of topics, topicPartitions or topicPattern must are allowed for <endpoint>","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/SimpleKafkaListenerEndpoint.java","lineNumber":176,"sourceCode":"\n    @Override\n    public String getMainListenerId() {\n        return mainListenerId;\n    }\n\n    public void setMainListenerId(String mainListenerId) {\n        this.mainListenerId = mainListenerId;\n    }\n\n    @Override\n    public void afterPropertiesSet() throws Exception {\n        boolean topicsEmpty = getTopics().isEmpty();\n        boolean topicPartitionsEmpty = ObjectUtils.isEmpty(getTopicPartitionsToAssign());\n        if (!topicsEmpty && !topicPartitionsEmpty) {\n            throw new IllegalStateException(\"Topics or topicPartitions must be provided but not both for \" + this);\n        }\n        if (this.topicPattern != null && (!topicsEmpty || !topicPartitionsEmpty)) {\n            throw new IllegalStateException(\"Only one of topics, topicPartitions or topicPattern must are allowed for \"\n                    + this);\n        }\n        if (this.topicPattern == null && topicsEmpty && topicPartitionsEmpty) {\n            throw new IllegalStateException(\"At least one of topics, topicPartitions or topicPattern must be provided \"\n                    + \"for \" + this);\n        }\n    }\n\n    @Override\n    public String toString() {\n        return getClass().getSimpleName() + \"[\" + this.id\n            + \"] topics=\" + this.topics\n            + \"' | topicPattern='\" + this.topicPattern + \"'\"\n            + \"' | topicPartitions='\" + this.topicPartitions + \"'\"\n            + \" | messageListener='\" + messageListener + \"'\";\n    }\n}\n","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/SimpleKafkaListenerEndpoint.java#L158-L194","documentation":"A SimpleKafkaListenerEndpoint may specify exactly one subscription mode: explicit topics, explicit topicPartitions, or a topic regex pattern. This error is thrown when a topicPattern is set AND topics or topicPartitions are also set, which would make the subscription ambiguous.","triggerScenarios":"Setting setTopicPattern(...) together with a non-empty setTopics(...) or setTopicPartitionsToAssign(...) on the same endpoint, validated in afterPropertiesSet.","commonSituations":"Template/base endpoint that already sets topicPattern getting topics added dynamically; annotation-derived config merged with programmatic pattern config; misunderstanding that pattern plus concrete topics is additive (it is not).","solutions":["Remove setTopics(...) and setTopicPartitionsToAssign(...) when using setTopicPattern(...)","If concrete topics are needed, drop setTopicPattern(...) and list them in setTopics(...) only","Ensure any shared base/builder object does not carry over a previously set topicPattern"],"exampleFix":"// before\nendpoint.setTopicPattern(Pattern.compile(\"events\\\\..*\"));\nendpoint.setTopics(Collections.singletonList(\"events.main\"));\n// after\nendpoint.setTopicPattern(Pattern.compile(\"events\\\\..*\"));","handlingStrategy":"validation","validationCode":"if (endpoint.getTopicPattern() != null && (!endpoint.getTopics().isEmpty() || !ObjectUtils.isEmpty(endpoint.getTopicPartitionsToAssign()))) {\n    throw new IllegalArgumentException(\"topicPattern is mutually exclusive with topics and topicPartitions\");\n}","typeGuard":"boolean hasPatternConflict(SimpleKafkaListenerEndpoint e) {\n    return e.getTopicPattern() != null && (!e.getTopics().isEmpty() || !ObjectUtils.isEmpty(e.getTopicPartitionsToAssign()));\n}","tryCatchPattern":"try {\n    endpoint.afterPropertiesSet();\n} catch (IllegalStateException ex) {\n    throw new IllegalArgumentException(\"Fix endpoint: \" + ex.getMessage(), ex);\n}","preventionTips":["Never set topicPattern on endpoints intended for concrete topic lists","Reset or use fresh endpoint objects instead of mutating shared templates","Add an early assertion when merging annotation-derived and programmatic config"],"tags":["kafka","configuration","spring"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}