{"record":{"id":"f0f3136f0ad8d651","repo":"flowable/flowable-engine","slug":"involvedgroups-are-null-f0f313","errorCode":null,"errorMessage":"involvedGroups are null","messagePattern":"involvedGroups are null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/HistoricProcessInstanceQueryImpl.java","lineNumber":638,"sourceCode":"    public HistoricProcessInstanceQuery involvedGroup(String groupId, String identityLinkType) {\n        if (groupId == null) {\n            throw new FlowableIllegalArgumentException(\"groupId is null\");\n        }\n        if (identityLinkType == null) {\n            throw new FlowableIllegalArgumentException(\"identityLinkType is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.involvedGroupIdentityLink = new IdentityLinkQueryObject(null, groupId, identityLinkType);\n        } else {\n            this.involvedGroupIdentityLink = new IdentityLinkQueryObject(null, groupId, identityLinkType);\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricProcessInstanceQuery involvedGroups(Set<String> involvedGroups) {\n        if (involvedGroups == null) {\n            throw new FlowableIllegalArgumentException(\"involvedGroups are null\");\n        }\n        if (involvedGroups.isEmpty()) {\n            throw new FlowableIllegalArgumentException(\"involvedGroups are empty\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.involvedGroups = involvedGroups;\n        } else {\n            this.involvedGroups = involvedGroups;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricProcessInstanceQuery includeProcessVariables() {\n        this.includeProcessVariables = true;\n        return this;\n    }\n","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/HistoricProcessInstanceQueryImpl.java#L620-L656","documentation":"HistoricProcessInstanceQuery.involvedGroups(Set<String>) requires a non-null set of group ids. Flowable throws FlowableIllegalArgumentException when involvedGroups is null, preventing an undefined IN filter on group identity links. The check runs eagerly when building the query.","triggerScenarios":"Calling involvedGroups(groups) with a null set — e.g. the group set comes from a membership lookup returning null, an uninitialized field, or a nullable request parameter.","commonSituations":"Authorization-scoped history queries where user group resolution failed; bulk queries built from config that omitted the group list; refactors changing empty-set defaults to null.","solutions":["Initialize the set before the call, e.g. Set<String> groups = new HashSet<>(...);","Null-check and skip the criterion or fall back to another filter when null","Use Collections.emptySet() semantics explicitly: only call involvedGroups when groups != null","If the user has no groups, decide the intended result (no filter vs empty result) and code accordingly"],"exampleFix":"// before\nquery.involvedGroups(groups); // throws when groups == null\n// after\nif (groups != null && !groups.isEmpty()) {\n    query.involvedGroups(groups);\n}","handlingStrategy":"validation","validationCode":"if (groups == null) {\n    throw new IllegalArgumentException(\"involvedGroups must be non-null\");\n}\nif (!groups.isEmpty()) {\n    query.involvedGroups(groups);\n}","typeGuard":"boolean isValidGroupSet(Set<String> groups) {\n    return groups != null;\n}","tryCatchPattern":"try {\n    query.involvedGroups(groups);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"null\")) {\n        groups = Collections.emptySet(); // then decide on empty-set behavior\n    } else {\n        throw e;\n    }\n}","preventionTips":["Initialize group collections eagerly rather than leaving fields null","Return Collections.emptySet() from membership lookups instead of null","Validate query-builder inputs in a single helper layer","Distinguish 'no filter' from 'no groups' explicitly in your API design"],"tags":["flowable","null-check","identity-link","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"}