{"record":{"id":"4ad849b339101dcd","repo":"apache/pulsar","slug":"invalid-null-domain","errorCode":null,"errorMessage":"invalid null domain","messagePattern":"invalid null domain","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-common/src/main/java/org/apache/pulsar/common/naming/NamespaceName.java","lineNumber":135,"sourceCode":"\n    public String getLocalName() {\n        return localName;\n    }\n\n    public String getPersistentTopicName(String localTopic) {\n        return getTopicName(TopicDomain.persistent, localTopic);\n    }\n\n    /**\n     * Compose the topic name from namespace + topic.\n     *\n     * @param domain\n     * @param topic\n     * @return\n     */\n    String getTopicName(TopicDomain domain, String topic) {\n        if (domain == null) {\n            throw new IllegalArgumentException(\"invalid null domain\");\n        }\n        NamedEntity.checkName(topic);\n        return String.format(\"%s://%s/%s\", domain.toString(), namespace, topic);\n    }\n\n    @Override\n    public String toString() {\n        return namespace;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (obj instanceof NamespaceName) {\n            NamespaceName other = (NamespaceName) obj;\n            return Objects.equals(namespace, other.namespace);\n        }\n\n        return false;","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-common/src/main/java/org/apache/pulsar/common/naming/NamespaceName.java#L117-L153","documentation":"NamespaceName.getTopicName(domain, topic) composes 'domain://namespace/topic' and throws this IllegalArgumentException when the TopicDomain argument is null. It is a defensive programmer-error check: a null domain cannot produce a valid topic URL.","triggerScenarios":"Invoking getPersistentTopicName / package-private getTopicName with a null TopicDomain, e.g. passing an unset enum variable or the result of a lookup that returned null instead of TopicDomain.persistent.","commonSituations":"Code that resolves TopicDomain from config or a string via valueOf with a null input; refactored code where a domain constant became null; building topic names generically where the domain parameter is optional elsewhere but required here.","solutions":["Pass an explicit TopicDomain, typically TopicDomain.persistent for normal topics, e.g. namespace.getPersistentTopicName(topic).","If the domain comes from a string, map it defensively: TopicDomain.valueOf(str) with a null/empty check or default to persistent.","Check whether the calling code path should have used a higher-level TopicName API instead of constructing the name manually."],"exampleFix":"// before\nTopicDomain domain = lookupDomain(cfg); // may return null\nString name = ns.getTopicName(domain, topic);\n// after\nTopicDomain domain = Optional.ofNullable(lookupDomain(cfg)).orElse(TopicDomain.persistent);\nString name = ns.getTopicName(domain, topic);","handlingStrategy":"type-guard","validationCode":"if (domain == null) {\n    domain = TopicDomain.persistent; // or reject the input earlier\n}\nString name = ns.getTopicName(domain, topic);","typeGuard":"static TopicDomain requireDomain(TopicDomain d) {\n    if (d == null) throw new IllegalArgumentException(\"TopicDomain is required\");\n    return d;\n}","tryCatchPattern":"try {\n    String name = ns.getTopicName(domain, topic);\n} catch (IllegalArgumentException e) {\n    if (\"invalid null domain\".equals(e.getMessage())) {\n        domain = TopicDomain.persistent;\n    } else {\n        throw e;\n    }\n}","preventionTips":["Prefer getPersistentTopicName(topic) over the generic getTopicName(domain, topic) when the domain is always persistent.","Use an enum with a well-defined default instead of a nullable TopicDomain variable.","Never let domain strings from config map to null; use valueOf with fallback handling."],"tags":["pulsar","topic","null-argument","illegal-argument"],"backgroundTag":"null-required-argument","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}