{"record":{"id":"8aaea2288a82e0e1","repo":"apache/rocketmq","slug":"add-subscription-exception","errorCode":null,"errorMessage":"add subscription exception","messagePattern":"add subscription exception","errorType":"exception","errorClass":"MQClientException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/org/apache/rocketmq/client/consumer/DefaultMQPullConsumer.java","lineNumber":279,"sourceCode":"        this.registerTopics = withNamespace(registerTopics);\n    }\n\n    public Set<SubscriptionData> getRegisterSubscriptions() {\n        return registerSubscriptions;\n    }\n\n    public void addRegisterSubscriptions(String topic, MessageSelector messageSelector) throws MQClientException {\n        try {\n            if (messageSelector == null) {\n                messageSelector = MessageSelector.byTag(SubscriptionData.SUB_ALL);\n            }\n\n            SubscriptionData subscriptionData = FilterAPI.build(withNamespace(topic),\n                messageSelector.getExpression(), messageSelector.getExpressionType());\n\n            this.registerSubscriptions.add(subscriptionData);\n        } catch (Exception e) {\n            throw new MQClientException(\"add subscription exception\", e);\n        }\n    }\n\n    public void clearRegisterSubscriptions() {\n        this.registerSubscriptions.clear();\n    }\n\n    /**\n     * This method will be removed or it's visibility will be changed in a certain version after April 5, 2020, so\n     * please do not use this method.\n     */\n    @Deprecated\n    @Override\n    public void sendMessageBack(MessageExt msg, int delayLevel)\n        throws RemotingException, MQBrokerException, InterruptedException, MQClientException {\n        msg.setTopic(withNamespace(msg.getTopic()));\n        this.defaultMQPullConsumerImpl.sendMessageBack(msg, delayLevel, msg.getBrokerName());\n    }","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/client/src/main/java/org/apache/rocketmq/client/consumer/DefaultMQPullConsumer.java#L261-L297","documentation":"DefaultMQPullConsumer.addRegisterSubscriptions builds a SubscriptionData via FilterAPI.build(topic, expression, expressionType) and wraps ANY failure in MQClientException('add subscription exception'). The underlying cause is almost always an invalid filter expression: a malformed tag expression, an invalid EXPRESSION_TYPE (only TAG and SQL92 are valid), or a null expression with a non-TAG type. The cause chain (e) carries the real reason from FilterAPI/SubscriptionData.","triggerScenarios":"Calling addRegisterSubscriptions(topic, MessageSelector.bySql(\"invalid SQL ~~\")) — SQL92 parse failure; passing a selector whose expression type string is neither 'TAG' nor 'SQL92'; a tag expression like 'a && ' that fails tag parsing.","commonSituations":"Switching a consumer from tag filtering to SQL92 filtering with a syntax error; copy-pasting SQL92 expressions into a TAG selector; building MessageSelector manually with a wrong expressionType constant instead of byTag/bySql factories.","solutions":["Read the wrapped cause (e.getCause()) — it states the exact expression error","Use the factories: MessageSelector.byTag(\"TagA || TagB\") or MessageSelector.bySql(\"a > 5\") instead of hand-built selectors","For SQL92, enable and verify broker config enablePropertyFilter=true and use valid SQL92 syntax (comparisons on properties, not tags)","Pass null selector only if you accept SUB_ALL tags; do not mix a null expression with SQL92 type"],"exampleFix":"// before\nconsumer.addRegisterSubscriptions(\"TopicT\", MessageSelector.bySql(\"tags is 'a' AND\")); // malformed SQL92\n\n// after\nconsumer.addRegisterSubscriptions(\"TopicT\", MessageSelector.bySql(\"a BETWEEN 1 AND 5\"));","handlingStrategy":"try-catch","validationCode":"// Prefer factory selectors; sanity-check SQL92 before registering\nif (selector != null && \"SQL92\".equals(selector.getExpressionType())\n        && selector.getExpression() == null) {\n    throw new IllegalArgumentException(\"SQL92 selector requires an expression\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    consumer.addRegisterSubscriptions(topic, selector);\n} catch (MQClientException e) {\n    Throwable cause = e.getCause(); // real expression parse error\n    log.error(\"Bad subscription for {}: {}\", topic, cause.getMessage());\n    // fix expression or fall back to MessageSelector.byTag(\"*\")\n}","preventionTips":["Always use MessageSelector.byTag/bySql factories","Test SQL92 expressions in a staging broker with enablePropertyFilter=true before shipping","Log the cause chain, not just the wrapper message"],"tags":["consumer","subscription","filter","validation"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}