{"record":{"id":"407218d492405726","repo":"flowable/flowable-engine","slug":"userid-is-null-407218","errorCode":null,"errorMessage":"userId is null","messagePattern":"userId is null","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":311,"sourceCode":"        this.withLocalizationFallback = true;\n        return this;\n    }\n\n    public Collection<String> getAuthorizationGroups() {\n        // if authorizationGroupsSet is true then startableByUserOrGroups was called\n        // and the groups passed in that methods have precedence\n        if (authorizationGroupsSet) {\n            return authorizationGroups;\n        } 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","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/repository/CaseDefinitionQueryImpl.java#L293-L329","documentation":"startableByUser in CaseDefinitionQueryImpl throws FlowableIllegalArgumentException with \"userId is null\" when the userId argument is null. The filter restricts case definitions to those startable by the given user, so a null user is meaningless and rejected eagerly.","triggerScenarios":"Calling startableByUser(null) — commonly when the authenticated user could not be resolved (anonymous request, missing security context, failed identity lookup).","commonSituations":"Security context not populated because authentication was skipped in tests; passing the result of a user lookup that returns null for unknown users; running outside a web session (batch jobs) where no user exists.","solutions":["Resolve the current authenticated user first and only call startableByUser with a non-null id.","If authorization is not needed, omit the startableByUser filter rather than passing null.","Return 401/403 to the caller when no user is present instead of building the query."],"exampleFix":"// before\nquery.startableByUser(securityService.getCurrentUser().getId());\n\n// after\nUser user = securityService.getCurrentUser();\nif (user != null) {\n    query.startableByUser(user.getId());\n} else {\n    throw new SecurityException(\"authenticated user required\");\n}","handlingStrategy":"validation","validationCode":"String userId = securityService.getCurrentUserId();\nif (userId != null) {\n    query.startableByUser(userId);\n}","typeGuard":"boolean isAuthenticated(Principal p) { return p != null && p.getName() != null; }","tryCatchPattern":"try {\n    query.startableByUser(userId);\n} catch (FlowableIllegalArgumentException e) {\n    if (!e.getMessage().contains(\"userId is null\")) throw e;\n    throw new SecurityException(\"user must be authenticated\");\n}","preventionTips":["Require authentication before building authorization-filtered queries","Never pass identity-lookup results without a null check","In tests, stub the security context instead of leaving it null"],"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"}