{"record":{"id":"0749bf8355500a38","repo":"flowable/flowable-engine","slug":"set-of-process-instance-ids-is-empty-0749bf","errorCode":null,"errorMessage":"Set of process instance ids is empty","messagePattern":"Set of process instance ids is empty","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/HistoricProcessInstanceQueryImpl.java","lineNumber":110,"sourceCode":"    }\n\n    @Override\n    public HistoricProcessInstanceQueryImpl processInstanceId(String processInstanceId) {\n        if (inOrStatement) {\n            this.currentOrQueryObject.processInstanceId = processInstanceId;\n        } else {\n            this.processInstanceId = processInstanceId;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricProcessInstanceQuery processInstanceIds(Set<String> processInstanceIds) {\n        if (processInstanceIds == null) {\n            throw new ActivitiIllegalArgumentException(\"Set of process instance ids is null\");\n        }\n        if (processInstanceIds.isEmpty()) {\n            throw new ActivitiIllegalArgumentException(\"Set of process instance ids is empty\");\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.processInstanceIds = processInstanceIds;\n        } else {\n            this.processInstanceIds = processInstanceIds;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricProcessInstanceQueryImpl processDefinitionId(String processDefinitionId) {\n        if (inOrStatement) {\n            this.currentOrQueryObject.processDefinitionId = processDefinitionId;\n        } else {\n            this.processDefinitionId = processDefinitionId;\n        }\n        return this;","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/HistoricProcessInstanceQueryImpl.java#L92-L128","documentation":"HistoricProcessInstanceQuery.processInstanceIds(Set<String>) also rejects an empty set with ActivitiIllegalArgumentException, because an empty IN-clause would match nothing and usually indicates a caller bug rather than an intentional filter. You must supply at least one process instance id.","triggerScenarios":"Calling processInstanceIds(new HashSet<>()) or passing a set that was emptied by prior filtering — e.g. ids collected from a search that returned zero matches.","commonSituations":"Batch job with no work items after filtering; UI passing through an empty selection; upstream query returning no rows and the empty collection being forwarded unchanged.","solutions":["Only call processInstanceIds when the set has at least one element; otherwise skip the filter or return an empty result directly.","Validate inputs before the call: if (ids == null || ids.isEmpty()) handle explicitly.","Fix the id-collection step so it either produces real ids or signals 'nothing to do'.","In batch flows, short-circuit the query when the id set is empty."],"exampleFix":"// before\nSet<String> ids = findCandidateIds(); // may be empty\nquery.processInstanceIds(ids);\nList<HistoricProcessInstance> r = query.list();\n// after\nSet<String> ids = findCandidateIds();\nList<HistoricProcessInstance> r = ids.isEmpty()\n    ? Collections.emptyList()\n    : historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list();","handlingStrategy":"validation","validationCode":"if (ids == null || ids.isEmpty()) {\n    return Collections.emptyList(); // nothing to look up\n}\nquery.processInstanceIds(ids);","typeGuard":"boolean hasIds(java.util.Collection<?> c) { return c != null && !c.isEmpty(); }","tryCatchPattern":"try {\n    query.processInstanceIds(ids);\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"is empty\")) {\n        // treat as empty result or fix id collection step\n    }\n}","preventionTips":["Short-circuit queries when the id set is empty.","Don't forward raw upstream collections into IN-clause filters.","Log/monitor empty id sets in batch jobs to catch producer bugs.","Distinguish 'no input' (skip) from 'no results' (empty response)."],"tags":["java","activiti","query","empty-collection"],"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"}