{"record":{"id":"30726c37170c8312","repo":"flowable/flowable-engine","slug":"userid-is-null-and-groups-are-null-or-empty","errorCode":null,"errorMessage":"userId is null and groups are null or empty","messagePattern":"userId is null and groups are null or empty","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/repository/CaseDefinitionQueryImpl.java","lineNumber":320,"sourceCode":"        } else if (authorizationUserId == null) {\n            return null;\n        }\n        return CommandContextUtil.getCmmnEngineConfiguration().getCandidateManager().getGroupsForCandidateUser(authorizationUserId);\n    }\n    \n    @Override\n    public CaseDefinitionQuery startableByUser(String userId) {\n        if (userId == null) {\n            throw new FlowableIllegalArgumentException(\"userId is null\");\n        }\n        this.authorizationUserId = userId;\n        return this;\n    }\n\n    @Override\n    public CaseDefinitionQuery startableByUserOrGroups(String userId, Collection<String> groups) {\n        if (userId == null && (groups == null || groups.isEmpty())) {\n            throw new FlowableIllegalArgumentException(\"userId is null and groups are null or empty\");\n        }\n        this.authorizationUserId = userId;\n        this.authorizationGroups = groups;\n        this.authorizationGroupsSet = true;\n        return this;\n    }\n\n    // sorting ////////////////////////////////////////////\n\n    @Override\n    public CaseDefinitionQuery orderByDeploymentId() {\n        return orderBy(CaseDefinitionQueryProperty.CASE_DEFINITION_DEPLOYMENT_ID);\n    }\n\n    @Override\n    public CaseDefinitionQuery orderByCaseDefinitionKey() {\n        return orderBy(CaseDefinitionQueryProperty.CASE_DEFINITION_KEY);\n    }","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/repository/CaseDefinitionQueryImpl.java#L302-L338","documentation":"startableByUserOrGroups in CaseDefinitionQueryImpl throws FlowableIllegalArgumentException with \"userId is null and groups are null or empty\" when both inputs are effectively empty. The method supports an OR filter (user id and/or group membership); at least one of the two must be provided, otherwise the authorization filter would be undefined.","triggerScenarios":"Calling startableByUserOrGroups(null, null) or startableByUserOrGroups(null, Collections.emptyList()) — e.g. when identity resolution returned neither a user nor group memberships.","commonSituations":"Unauthenticated sessions where user id and groups are both unavailable; a group-fetching service failing silently and returning an empty collection; wiring the wrong (unpopulated) identity object into the query.","solutions":["Validate that at least one of userId or a non-empty groups collection exists before calling; otherwise skip the filter or reject the request.","Fix group resolution so membership is fetched (e.g. via identityService) before building the query.","Require authentication earlier in the flow so user id or groups are always available."],"exampleFix":"// before\nquery.startableByUserOrGroups(userId, groups);\n\n// after\nboolean hasUser = userId != null;\nboolean hasGroups = groups != null && !groups.isEmpty();\nif (hasUser || hasGroups) {\n    query.startableByUserOrGroups(userId, groups);\n} else {\n    throw new SecurityException(\"user or groups required\");\n}","handlingStrategy":"validation","validationCode":"boolean ok = userId != null || (groups != null && !groups.isEmpty());\nif (ok) {\n    query.startableByUserOrGroups(userId, groups);\n} else {\n    throw new SecurityException(\"userId or groups required\");\n}","typeGuard":"boolean hasIdentity(String u, java.util.Collection<String> g) {\n    return u != null || (g != null && !g.isEmpty());\n}","tryCatchPattern":"try {\n    query.startableByUserOrGroups(userId, groups);\n} catch (FlowableIllegalArgumentException e) {\n    if (!e.getMessage().contains(\"groups are null or empty\")) throw e;\n    throw new SecurityException(\"no identity information available\");\n}","preventionTips":["Fetch group memberships before building the query","Fail fast on unauthenticated requests rather than passing nulls through","Encapsulate user-or-groups resolution in one utility with a non-empty guarantee"],"tags":["null-argument","authorization","query-builder","cmmn"],"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"}