{"record":{"id":"e4c535883a29994d","repo":"openzipkin/zipkin","slug":"topic-is-null-or-empty","errorCode":null,"errorMessage":"topic is null or empty","messagePattern":"topic is null or empty","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"zipkin-collector/pulsar/src/main/java/zipkin2/collector/pulsar/PulsarCollector.java","lineNumber":71,"sourceCode":"      this.delegate.sampler(sampler);\n      return this;\n    }\n\n    @Override\n    public PulsarCollector build() {\n      return new PulsarCollector(this);\n    }\n\n    /** Count of concurrent message consumers on the topic. Defaults to 1. */\n    public Builder concurrency(Integer concurrency) {\n      if (concurrency < 1) throw new IllegalArgumentException(\"concurrency < 1\");\n      this.concurrency = concurrency;\n      return this;\n    }\n\n    /** Queue zipkin spans will be consumed from. Defaults to \"zipkin\". */\n    public Builder topic(String topic) {\n      if (StringUtils.isNullOrEmpty(topic)) throw new NullPointerException(\"topic is null or empty\");\n      this.topic = topic;\n      return this;\n    }\n\n    /** The service URL for the Pulsar client ex. pulsar://my-broker:6650. No default. */\n    public Builder serviceUrl(String serviceUrl) {\n      if (StringUtils.isNullOrEmpty(serviceUrl)) throw new NullPointerException(\"serviceUrl is null or empty\");\n      clientProps.put(\"serviceUrl\", serviceUrl);\n      return this;\n    }\n\n    /** Specify the subscription name for this consumer. No default. */\n    public Builder subscriptionName(String subscriptionName) {\n      if (StringUtils.isNullOrEmpty(subscriptionName)) throw new NullPointerException(\"serviceUrl is null or empty\");\n      consumerProps.put(\"subscriptionName\", subscriptionName);\n      return this;\n    }\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-collector/pulsar/src/main/java/zipkin2/collector/pulsar/PulsarCollector.java#L53-L89","documentation":"PulsarCollector.Builder.topic(String) throws NullPointerException when the topic is null or empty (checked with StringUtils.isNullOrEmpty). The topic is the queue zipkin spans are consumed from (default \"zipkin\"); an empty string is treated as a misconfiguration, not just null. Fail-fast at builder time.","triggerScenarios":"Calling .topic(null) or .topic(\"\") — e.g. reading the topic name from a config key that is absent (null) or present but blank.","commonSituations":"Optional topic config rendered as an empty string in YAML/JSON bindings, or trimming user input to \"\" before passing it in.","solutions":["Pass a concrete topic name, e.g. .topic(\"zipkin\")","Default missing config at read time: getOrDefault(\"pulsar.topic\", \"zipkin\") and treat blank as unset","Omit the topic() call entirely to keep the default \"zipkin\""],"exampleFix":"// before\nbuilder.topic(config.get(\"topic\").trim()); // \"\" when key absent\n\n// after\nString topic = config.getOrDefault(\"topic\", \"zipkin\").trim();\nif (topic.isEmpty()) topic = \"zipkin\";\nbuilder.topic(topic);","handlingStrategy":"validation","validationCode":"String topic = config.getOrDefault(\"pulsar.topic\", \"zipkin\");\nif (topic == null || topic.trim().isEmpty()) topic = \"zipkin\";\nbuilder.topic(topic);","typeGuard":"static boolean isMeaningful(String s) { return s != null && !s.trim().isEmpty(); }","tryCatchPattern":null,"preventionTips":["Normalize blank strings to defaults at the config boundary","Remember empty string is rejected too, not just null"],"tags":["pulsar","zipkin","builder","null-check","topic"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}