{"record":{"id":"878470650765618e","repo":"flowable/flowable-engine","slug":"set-of-process-definition-ids-is-empty-878470","errorCode":null,"errorMessage":"Set of process definition ids is empty","messagePattern":"Set of process definition ids is empty","errorType":"exception","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessInstanceQueryImpl.java","lineNumber":251,"sourceCode":"        if (processDefinitionId == null) {\n            throw new ActivitiIllegalArgumentException(\"Process definition id is null\");\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.processDefinitionId = processDefinitionId;\n        } else {\n            this.processDefinitionId = processDefinitionId;\n        }\n        return this;\n    }\n\n    @Override\n    public ProcessInstanceQuery processDefinitionIds(Set<String> processDefinitionIds) {\n        if (processDefinitionIds == null) {\n            throw new ActivitiIllegalArgumentException(\"Set of process definition ids is null\");\n        }\n        if (processDefinitionIds.isEmpty()) {\n            throw new ActivitiIllegalArgumentException(\"Set of process definition ids is empty\");\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.processDefinitionIds = processDefinitionIds;\n        } else {\n            this.processDefinitionIds = processDefinitionIds;\n        }\n        return this;\n    }\n\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;","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessInstanceQueryImpl.java#L233-L269","documentation":"ProcessInstanceQueryImpl.processDefinitionIds(Set<String>) throws ActivitiIllegalArgumentException with message 'Set of process definition ids is empty' when the set is non-null but has no elements. An empty IN clause is invalid SQL semantically (it would match nothing or be unparseable), so the API rejects it upfront. If you want no filtering, do not call the method at all.","triggerScenarios":"Calling .processDefinitionIds(Collections.emptySet()) or passing a set that was filtered down to zero elements before query construction — common when authorization or tenant filtering removes all candidates.","commonSituations":"Access-control logic that yields an empty allowed-definitions set; downstream filtering (stream().filter()) emptying a populated list; loading ids from an empty DB table or missing config.","solutions":["Check set size before calling; if empty, either return an empty result immediately without executing the query or omit the filter if 'all' is intended.","Decide semantics explicitly: empty allowed-set usually means 'no access', so short-circuit to an empty response rather than querying.","Ensure upstream data (allowed definitions, tenant config) is loaded and non-empty where it is required.","Catch ActivitiIllegalArgumentException and translate it into a business-level message about no accessible definitions."],"exampleFix":"// before\nSet<String> ids = loadAllowedDefinitionIds(user);\nProcessInstanceQuery q = query.processDefinitionIds(ids); // throws when empty\n// after\nSet<String> ids = loadAllowedDefinitionIds(user);\nif (ids.isEmpty()) return Collections.emptyList();\nProcessInstanceQuery q = query.processDefinitionIds(ids);","handlingStrategy":"validation","validationCode":"if (ids != null && ids.isEmpty()) {\n    return Collections.emptyList(); // empty allowed-set means no accessible definitions\n}\nif (ids != null) {\n    query = query.processDefinitionIds(ids);\n}","typeGuard":"boolean isQueryableSet(Set<String> s) { return s != null && !s.isEmpty(); }","tryCatchPattern":"try {\n    result = query.processDefinitionIds(ids).list();\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"process definition ids is empty\")) {\n        return Collections.emptyList(); // semantically: nothing matches an empty IN clause\n    }\n    throw e;\n}","preventionTips":["Decide the semantics of an empty set upfront: empty result vs no filter.","Re-check set size after stream filtering/mapping operations that may empty it.","Return early on empty authorization results instead of querying.","Add tests for the empty-collection path of your query builder."],"tags":["java","activiti","flowable","empty-collection","query-validation"],"backgroundTag":"empty-required-field","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"}