{"record":{"id":"b3eb1c22d6f181bd","repo":"flowable/flowable-engine","slug":"task-id-list-is-null","errorCode":null,"errorMessage":"Task id list is null","messagePattern":"Task 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":713,"sourceCode":"            this.cmmnDeploymentIds = cmmnDeploymentIds;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricTaskInstanceQuery taskId(String taskId) {\n        if (inOrStatement) {\n            this.currentOrQueryObject.taskId = taskId;\n        } else {\n            this.taskId = taskId;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricTaskInstanceQuery taskIds(Collection<String> taskIds) {\n        if (taskIds == null) {\n            throw new FlowableIllegalArgumentException(\"Task id list is null\");\n        }\n        if (taskIds.isEmpty()) {\n            throw new FlowableIllegalArgumentException(\"Task id list is empty\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.taskIds = taskIds;\n        } else {\n            this.taskIds = taskIds;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricTaskInstanceQuery taskName(String taskName) {\n        if (inOrStatement) {\n            this.currentOrQueryObject.taskName = taskName;\n        } else {\n            this.taskName = taskName;","sourceCodeStart":695,"sourceCodeEnd":731,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java#L695-L731","documentation":"HistoricTaskInstanceQueryImpl.taskIds(Collection) throws FlowableIllegalArgumentException when the taskIds collection is null. The collection feeds the query's IN clause over task IDs, which requires a concrete set of identifiers. Flowable validates this eagerly so the failure surfaces at query construction instead of at SQL execution.","triggerScenarios":"Calling historicTaskInstanceQuery().taskIds(null), typically when the ID collection comes from an uninitialized variable or a null-returning lookup.","commonSituations":"Result of a previous search/cache miss returned null; conditional code path never populated the collection; API callers passing null intending 'no filter'.","solutions":["Initialize the collection before use (e.g. new ArrayList<>()).","Guard the call: only pass taskIds when the reference is non-null and non-empty.","If the intent is 'no filtering by IDs', omit the taskIds call entirely."],"exampleFix":"// before\nquery.taskIds(collectedTaskIds); // may be null\n// after\nif (collectedTaskIds != null && !collectedTaskIds.isEmpty()) {\n    query.taskIds(collectedTaskIds);\n}","handlingStrategy":"validation","validationCode":"if (taskIds == null || taskIds.isEmpty()) {\n    throw new IllegalArgumentException(\"taskIds requires a non-empty list\");\n}","typeGuard":"boolean hasTaskIds(Collection<String> ids) {\n    return ids != null && !ids.isEmpty();\n}","tryCatchPattern":"try {\n    query.taskIds(ids);\n} catch (FlowableIllegalArgumentException e) {\n    logger.warn(\"Invalid task id list: {}\", e.getMessage());\n}","preventionTips":["Initialize collections eagerly (new ArrayList<>()) so they are never null.","Skip the taskIds filter entirely when the intent is 'no ID restriction'.","Centralize Flowable query construction in a helper with guard clauses."],"tags":["flowable","query-builder","null-argument","argument-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"}