{"record":{"id":"9e4e15ba73ece06c","repo":"apache/pulsar","slug":"source-name-cannot-be-null","errorCode":null,"errorMessage":"Source name cannot be null","messagePattern":"Source name cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java","lineNumber":272,"sourceCode":"\n        if (!isEmpty(functionDetails.getCustomRuntimeOptions())) {\n            sourceConfig.setCustomRuntimeOptions(functionDetails.getCustomRuntimeOptions());\n        }\n\n        return sourceConfig;\n    }\n\n    public static ExtractedSourceDetails validateAndExtractDetails(SourceConfig sourceConfig,\n                                                                   ValidatableFunctionPackage sourceFunction,\n                                                                   boolean validateConnectorConfig) {\n        if (isEmpty(sourceConfig.getTenant())) {\n            throw new IllegalArgumentException(\"Source tenant cannot be null\");\n        }\n        if (isEmpty(sourceConfig.getNamespace())) {\n            throw new IllegalArgumentException(\"Source namespace cannot be null\");\n        }\n        if (isEmpty(sourceConfig.getName())) {\n            throw new IllegalArgumentException(\"Source name cannot be null\");\n        }\n        if (!isEmpty(sourceConfig.getTopicName()) && !TopicName.isValid(sourceConfig.getTopicName())) {\n            throw new IllegalArgumentException(\"Topic name is invalid\");\n        }\n        if (!isEmpty(sourceConfig.getLogTopic())) {\n            if (!TopicName.isValid(sourceConfig.getLogTopic())) {\n                throw new IllegalArgumentException(\n                        String.format(\"LogTopic topic %s is invalid\", sourceConfig.getLogTopic()));\n            }\n        }\n        if (sourceConfig.getParallelism() != null && sourceConfig.getParallelism() <= 0) {\n            throw new IllegalArgumentException(\"Source parallelism must be a positive number\");\n        }\n        if (sourceConfig.getResources() != null) {\n            ResourceConfigUtils.validate(sourceConfig.getResources());\n        }\n\n        String sourceClassName = sourceConfig.getClassName();","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java#L254-L290","documentation":"validateAndExtractDetails enforces that SourceConfig.name is non-null and non-empty, since the name completes the mandatory tenant/namespace/name identity of a source connector. It is the third required-field check, thrown after tenant and namespace validation succeed.","triggerScenarios":"Registering or validating a source whose SourceConfig has tenant and namespace set but name null or empty — e.g. a config file missing the 'name' key, or building SourceConfig dynamically and never calling setName().","commonSituations":"Generating SourceConfigs in loops where the name is derived from input that was blank; template configs with a placeholder name never substituted; REST/CLI callers omitting the name field.","solutions":["Set a non-empty name on the SourceConfig, e.g. sourceConfig.setName(\"kafka-source\")","If the name should be derived (e.g. from topic or connector), compute it before validation","Add pre-validation in your submission tooling to reject blank source names with a friendly message"],"exampleFix":"// before\nSourceConfig cfg = new SourceConfig();\ncfg.setTenant(\"public\");\ncfg.setNamespace(\"default\");\n// after\nSourceConfig cfg = new SourceConfig();\ncfg.setTenant(\"public\");\ncfg.setNamespace(\"default\");\ncfg.setName(\"kafka-source\");","handlingStrategy":"validation","validationCode":"if (cfg.getName() == null || cfg.getName().trim().isEmpty()) {\n    throw new IllegalArgumentException(\"sourceConfig.name must be a non-empty source name\");\n}","typeGuard":"static boolean hasName(SourceConfig cfg) {\n    return cfg != null && cfg.getName() != null && !cfg.getName().trim().isEmpty();\n}","tryCatchPattern":"try {\n    SourceConfigUtils.validateAndExtractDetails(cfg, pkg, true);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Source name cannot be null\")) {\n        // prompt for / default a source name before retrying\n    }\n}","preventionTips":["Derive the source name from a stable input (topic, connector id) and assert it is non-empty before submission","Never leave placeholder names in templates — fail your pipeline if placeholders remain","Check tenant/namespace/name as one unit before calling any Pulsar API"],"tags":["pulsar-functions","config-validation","illegal-argument"],"backgroundTag":"missing-required-config-field","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}