{"record":{"id":"5279288457d3199e","repo":"apache/pulsar","slug":"configproperties-cannot-be-null","errorCode":null,"errorMessage":"configProperties cannot be null","messagePattern":"configProperties cannot be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"tiered-storage/jcloud/src/main/java/org/apache/bookkeeper/mledger/offload/jcloud/provider/TieredStorageConfiguration.java","lineNumber":107,"sourceCode":"\n        return new TieredStorageConfiguration(map);\n    }\n\n    public static TieredStorageConfiguration create(Map<String, String> props) {\n        return new TieredStorageConfiguration(props);\n    }\n\n    @Getter\n    private final Map<String, String> configProperties;\n    @Getter\n    private Supplier<Credentials> credentials;\n    private JCloudBlobStoreProvider provider;\n\n    public TieredStorageConfiguration(Map<String, String> configProperties) {\n        if (configProperties != null) {\n            this.configProperties = configProperties;\n        } else {\n            throw new IllegalArgumentException(\"configProperties cannot be null\");\n        }\n    }\n\n    public List<String> getKeys(String property) {\n        List<String> keys = new ArrayList<String> ();\n\n        String bc = getBackwardCompatibleKey(property);\n        if (StringUtils.isNotBlank(bc)) {\n            keys.add(bc);\n        }\n\n        String key = getKeyName(property);\n        if (StringUtils.isNotBlank(key)) {\n            keys.add(key);\n        }\n        return keys;\n    }\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/tiered-storage/jcloud/src/main/java/org/apache/bookkeeper/mledger/offload/jcloud/provider/TieredStorageConfiguration.java#L89-L125","documentation":"Constructor guard on TieredStorageConfiguration: the configProperties map is the sole source of driver/endpoint/bucket/credential settings, so a null map cannot yield a usable configuration. The public constructor rejects null immediately with IllegalArgumentException instead of failing later with NPEs.","triggerScenarios":"Calling new TieredStorageConfiguration(null) — typically from code that loads a properties map from a file/keystore that returned null, or passes an uninitialized map variable.","commonSituations":"Plugin or custom offload driver constructing the config before properties are loaded; Properties-to-Map conversion returning null on missing resource; unit tests invoking the constructor with null.","solutions":["Pass an empty map (new HashMap<>()) instead of null if there are genuinely no properties.","Load the map from broker.conf / offload policies before constructing the configuration.","Add a null/empty check at the call site to surface the real source of the null map.","In tests, build a minimal map with driver/endpoint/bucket keys."],"exampleFix":"// before\nTieredStorageConfiguration cfg = new TieredStorageConfiguration(null);\n// after\nMap<String,String> props = loadOffloadProperties();\nTieredStorageConfiguration cfg = new TieredStorageConfiguration(\n    props != null ? props : new HashMap<>());","handlingStrategy":"type-guard","validationCode":"if (props == null) {\n    props = new HashMap<>();\n}\nTieredStorageConfiguration cfg = new TieredStorageConfiguration(props);","typeGuard":"static boolean hasProperties(Map<String, String> props) {\n    return props != null;\n}","tryCatchPattern":"try {\n    cfg = new TieredStorageConfiguration(props);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"configProperties cannot be null\")) {\n        cfg = new TieredStorageConfiguration(new HashMap<>());\n    }\n}","preventionTips":["Default to an empty map rather than null for optional property sets.","Null-check the result of property loading before constructing the configuration.","Avoid APIs that return null maps; prefer Optional<Map<...>> at your call sites.","Cover the constructor in unit tests with both null and empty-map cases."],"tags":["configuration","null-check","validation"],"backgroundTag":"null-argument","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"}