{"record":{"id":"e2818266592dad9f","repo":"flowable/flowable-engine","slug":"this-map-does-not-support-null-keys","errorCode":null,"errorMessage":"This map does not support 'null' keys.","messagePattern":"This map does not support 'null' keys\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cdi/src/main/java/org/flowable/cdi/impl/ProcessVariableMap.java","lineNumber":38,"sourceCode":"\r\nimport org.flowable.cdi.BusinessProcess;\r\n\r\n/**\r\n * Allows to expose the process variables of the current business process as a {@code java.util.Map<String,Object>}.\r\n * <p>\r\n * The map delegates changes to {@link BusinessProcess#setVariable(String, Object)} and {@link BusinessProcess#getVariable(String)}, so that they are not flushed prematurely.\r\n * \r\n * @author Daniel Meyer\r\n */\r\npublic class ProcessVariableMap implements Map<String, Object> {\r\n\r\n    @Inject\r\n    private BusinessProcess businessProcess;\r\n\r\n    @Override\r\n    public Object get(Object key) {\r\n        if (key == null) {\r\n            throw new IllegalArgumentException(\"This map does not support 'null' keys.\");\r\n        }\r\n        return businessProcess.getVariable(key.toString());\r\n    }\r\n\r\n    @Override\r\n    public Object put(String key, Object value) {\r\n        if (key == null) {\r\n            throw new IllegalArgumentException(\"This map does not support 'null' keys.\");\r\n        }\r\n        Object variableBefore = businessProcess.getVariable(key);\r\n        businessProcess.setVariable(key, value);\r\n        return variableBefore;\r\n    }\r\n\r\n    @Override\r\n    public void putAll(Map<? extends String, ? extends Object> m) {\r\n        for (Map.Entry<? extends String, ? extends Object> newEntry : m.entrySet()) {\r\n            businessProcess.setVariable(newEntry.getKey(), newEntry.getValue());\r","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cdi/src/main/java/org/flowable/cdi/impl/ProcessVariableMap.java#L20-L56","documentation":"ProcessVariableMap is a CDI-injected Map view over process variables backed by BusinessProcess. Its get(Object) method rejects null keys with IllegalArgumentException because a process variable cannot exist without a name; the map contract explicitly does not support null keys. The exception is thrown before any lookup against the process engine happens.","triggerScenarios":"Calling ProcessVariableMap.get(null), e.g. via code that dereferences a variable name that is null, or framework code (EL, templating, serialization libraries) that probes the map with a null key.","commonSituations":"A developer builds the map key from a config property or request parameter that is null/missing; a generic Map-writing helper passes null keys; a library iterating keys assumes null keys are allowed.","solutions":["Ensure the variable name is non-null before calling get(): check the source of the key (config, parameter) for null.","Wrap the map access in a null check: if (key != null) { map.get(key); }","If the key is legitimately absent, skip the lookup instead of calling get with null."],"exampleFix":"// before\nString varName = config.getVariableName();\nObject value = processVariableMap.get(varName);\n\n// after\nString varName = config.getVariableName();\nObject value = varName != null ? processVariableMap.get(varName) : null;","handlingStrategy":"validation","validationCode":"if (key == null) { throw new IllegalArgumentException(\"variable name must not be null\"); }\nObject value = processVariableMap.get(key);","typeGuard":"boolean isValidKey(Object key) { return key instanceof String && !((String) key).isEmpty(); }","tryCatchPattern":"try { value = processVariableMap.get(key); } catch (IllegalArgumentException e) { value = null; /* null key: skip */ }","preventionTips":["Never build the variable name from unvalidated config or request input","Null-check keys before any Map operation","Do not hand ProcessVariableMap to generic Map-consuming libraries"],"tags":["java","cdi","null-argument","map"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}