{"record":{"id":"aff968213013e421","repo":"apache/rocketmq","slug":"parse-subscription-error","errorCode":null,"errorMessage":"parse subscription error","messagePattern":"parse subscription error","errorType":"exception","errorClass":"MQClientException","httpStatus":null,"severity":"error","filePath":"client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPullConsumerImpl.java","lineNumber":210,"sourceCode":"    }\n\n    public PullResult pull(MessageQueue mq, MessageSelector messageSelector, long offset, int maxNums, long timeout)\n        throws MQClientException, RemotingException, MQBrokerException, InterruptedException {\n        SubscriptionData subscriptionData = getSubscriptionData(mq, messageSelector);\n        return this.pullSyncImpl(mq, subscriptionData, offset, maxNums, false, timeout);\n    }\n\n    private SubscriptionData getSubscriptionData(MessageQueue mq, String subExpression)\n        throws MQClientException {\n\n        if (null == mq) {\n            throw new MQClientException(\"mq is null\", null);\n        }\n\n        try {\n            return FilterAPI.buildSubscriptionData(mq.getTopic(), subExpression);\n        } catch (Exception e) {\n            throw new MQClientException(\"parse subscription error\", e);\n        }\n    }\n\n    private SubscriptionData getSubscriptionData(MessageQueue mq, MessageSelector messageSelector)\n        throws MQClientException {\n\n        if (null == mq) {\n            throw new MQClientException(\"mq is null\", null);\n        }\n\n        try {\n            return FilterAPI.build(mq.getTopic(),\n                messageSelector.getExpression(), messageSelector.getExpressionType());\n        } catch (Exception e) {\n            throw new MQClientException(\"parse subscription error\", e);\n        }\n    }\n","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/client/src/main/java/org/apache/rocketmq/client/impl/consumer/DefaultMQPullConsumerImpl.java#L192-L228","documentation":"The catch block of getSubscriptionData wraps any exception from FilterAPI.buildSubscriptionData(topic, subExpression) as MQClientException(\"parse subscription error\", cause). buildSubscriptionData parses a TAG expression; malformed expressions (illegal characters, unbalanced parts after splitting on '||') raise the underlying exception which is rethrown here.","triggerScenarios":"consumer.pull(mq, \"TAG A ||\", ...) with a trailing separator; subExpression containing characters illegal in a tag; expression built by string concatenation with a stray '||'.","commonSituations":"User-supplied tag filters; dynamically assembled OR-expressions where an operand is empty.","solutions":["Validate/normalize the expression: non-empty operands around each '||', no whitespace inside a tag unless intended","Call e.getCause() to see the precise parse failure from FilterAPI","Build expressions from a validated tag vocabulary rather than raw concatenation"],"exampleFix":"// before\nString expr = String.join(\"||\", tags); // may end with '||' if a tag is empty\nconsumer.pull(mq, expr, 0, 32, 3000);\n\n// after\nString expr = tags.stream().filter(t -> t != null && !t.trim().isEmpty()).collect(Collectors.joining(\"||\"));\nconsumer.pull(mq, expr, 0, 32, 3000);","handlingStrategy":"validation","validationCode":"String expr = Arrays.stream(subExpr.split(\"\\\\|\\\\|\"))\n    .map(String::trim)\n    .filter(s -> !s.isEmpty())\n    .collect(Collectors.joining(\"||\"));\nif (expr.isEmpty()) expr = \"*\";","typeGuard":null,"tryCatchPattern":"try {\n    consumer.pull(mq, expr, offset, maxNums, timeout);\n} catch (MQClientException e) {\n    if (e.getCause() != null) {\n        // parse failure — fix expression, never retry unchanged\n    }\n}","preventionTips":["Build tag expressions from validated, non-empty operands","Cover expression construction with unit tests that run FilterAPI.buildSubscriptionData"],"tags":["rocketmq","consumer","pull","tag-expression","parse-error"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}