{"record":{"id":"83bdf022fc09e2f4","repo":"flowable/flowable-engine","slug":"set-of-process-definition-keys-is-null-83bdf0","errorCode":null,"errorMessage":"Set of process definition keys is null","messagePattern":"Set of process definition keys is null","errorType":"exception","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessInstanceQueryImpl.java","lineNumber":279,"sourceCode":"\n    @Override\n    public ProcessInstanceQueryImpl processDefinitionKey(String processDefinitionKey) {\n        if (processDefinitionKey == null) {\n            throw new ActivitiIllegalArgumentException(\"Process definition key is null\");\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.processDefinitionKey = processDefinitionKey;\n        } else {\n            this.processDefinitionKey = processDefinitionKey;\n        }\n        return this;\n    }\n\n    @Override\n    public ProcessInstanceQuery processDefinitionKeys(Set<String> processDefinitionKeys) {\n        if (processDefinitionKeys == null) {\n            throw new ActivitiIllegalArgumentException(\"Set of process definition keys is null\");\n        }\n        if (processDefinitionKeys.isEmpty()) {\n            throw new ActivitiIllegalArgumentException(\"Set of process definition keys is empty\");\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.processDefinitionKeys = processDefinitionKeys;\n        } else {\n            this.processDefinitionKeys = processDefinitionKeys;\n        }\n        return this;\n    }\n\n    @Override\n    public ProcessInstanceQueryImpl deploymentId(String deploymentId) {\n        if (inOrStatement) {\n            this.currentOrQueryObject.deploymentId = deploymentId;\n        } else {","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessInstanceQueryImpl.java#L261-L297","documentation":"ProcessInstanceQueryImpl.processDefinitionKeys(Set<String>) throws ActivitiIllegalArgumentException with message 'Set of process definition keys is null' when the argument set is null (an empty set has its own distinct error). The IN-style key filter requires a concrete non-null set of keys; eager validation keeps malformed queries from reaching the database.","triggerScenarios":"Calling .processDefinitionKeys(null) — typically a Set field never initialized, a null return from a configuration/authorization lookup, or a DTO with a missing keys list.","commonSituations":"Tenant/permission loaders returning null when no mappings exist; JSON request bodies omitting the keys array; static filter defaults that were never assigned.","solutions":["Initialize collections eagerly (Collections.emptySet()) and treat empty as 'no filter' by skipping the call.","Null-check lookup results before passing them into the query.","Normalize deserialized DTOs: null list -> empty -> omit filter.","Catch ActivitiIllegalArgumentException around query construction for a clear validation message."],"exampleFix":"// before\nquery.processDefinitionKeys(config.getProcessKeys()); // may be null\n// after\nSet<String> keys = config.getProcessKeys();\nif (keys != null && !keys.isEmpty()) {\n    query = query.processDefinitionKeys(keys);\n}","handlingStrategy":"validation","validationCode":"if (keys == null || keys.isEmpty()) {\n    // skip filter or short-circuit\n}\nelse {\n    query = query.processDefinitionKeys(keys);\n}","typeGuard":"boolean isNonEmptyKeySet(Set<String> s) { return s != null && !s.isEmpty(); }","tryCatchPattern":"try {\n    result = query.processDefinitionKeys(keys).list();\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"process definition keys is null\")) {\n        throw new BadRequestException(\"processDefinitionKeys set must not be null\");\n    }\n    throw e;\n}","preventionTips":["Default collection fields to Collections.emptySet() and skip empty filters.","Null-check config/authorization loaders returning key sets before querying.","Normalize DTO key lists (null -> empty -> skip) in one mapping layer.","Add a regression test for the null-collection filter path."],"tags":["java","activiti","flowable","null-argument","collection","query-validation"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}