{"record":{"id":"4d77fb78080f3ef8","repo":"flowable/flowable-engine","slug":"process-instance-id-list-is-null","errorCode":null,"errorMessage":"Process instance id list is null","messagePattern":"Process instance id list is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java","lineNumber":301,"sourceCode":"                    .addAll(variableServiceConfiguration.getHistoricVariableInstanceEntityManager()\n                            .findHistoricalVariableInstancesByTaskId(task.getId()));\n        }\n    }\n\n    @Override\n    public HistoricTaskInstanceQueryImpl 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 HistoricTaskInstanceQueryImpl processInstanceIdIn(Collection<String> processInstanceIds) {\n        if (processInstanceIds == null) {\n            throw new FlowableIllegalArgumentException(\"Process instance id list is null\");\n        }\n        if (processInstanceIds.isEmpty()) {\n            throw new FlowableIllegalArgumentException(\"Process instance id list is empty\");\n        }\n        for (String processInstanceId : processInstanceIds) {\n            if (processInstanceId == null) {\n                throw new FlowableIllegalArgumentException(\"None of the given process instance ids can be null\");\n            }\n        }\n\n        if (inOrStatement) {\n            this.currentOrQueryObject.processInstanceIds = processInstanceIds;\n        } else {\n            this.processInstanceIds = processInstanceIds;\n        }\n        return this;\n    }\n    ","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java#L283-L319","documentation":"HistoricTaskInstanceQueryImpl.processInstanceIdIn(Collection<String>) validates its argument before storing it on the query. Passing a null collection immediately throws FlowableIllegalArgumentException('Process instance id list is null'). The query builder fails fast so the invalid predicate never reaches the SQL layer.","triggerScenarios":"Calling historicTaskInstanceQuery().processInstanceIdIn(null); typically when the collection is the result of an earlier lookup that returned null (uninitialized variable, absent map value).","commonSituations":"Building dynamic filters where processInstanceIds comes from an upstream API/service returning null when no instances apply; forgetting to initialize a list field; reflection-driven query construction passing null.","solutions":["Guard the call: only invoke processInstanceIdIn when the collection is non-null.","Replace null with an empty check upstream — decide whether to skip the predicate (no filter) or handle 'no instances' without querying.","If the source may return null, normalize it at the boundary (e.g. Collections.emptyList()) and branch on emptiness instead."],"exampleFix":"// before\nList<String> ids = lookupProcessInstanceIds(); // may be null\nquery.processInstanceIdIn(ids); // FlowableIllegalArgumentException\n\n// after\nif (ids != null && !ids.isEmpty()) {\n    query.processInstanceIdIn(ids);\n}","handlingStrategy":"type-guard","validationCode":"if (processInstanceIds == null) { processInstanceIds = Collections.emptyList(); }","typeGuard":"boolean isUsableIdList(Collection<String> c) { return c != null && !c.isEmpty(); }","tryCatchPattern":"try {\n    query.processInstanceIdIn(ids);\n} catch (FlowableIllegalArgumentException e) {\n    // fall back to unfiltered query or return empty result\n}","preventionTips":["Initialize id collections at declaration, never leave them null","Normalize null returns from upstream lookups to empty lists","Validate dynamic query inputs in a shared helper before building queries"],"tags":["query","null-argument","task-history","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-18T11:17:12.947Z"}