{"record":{"id":"e4798bd1eaed2d45","repo":"flowable/flowable-engine","slug":"user-id-is-null","errorCode":null,"errorMessage":"user id is null","messagePattern":"user id is null","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java","lineNumber":648,"sourceCode":"\n    @Override\n    public HistoricCaseInstanceQueryImpl startedAfter(Date afterTime) {\n        if (afterTime == null) {\n            throw new FlowableIllegalArgumentException(\"after time is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.startedAfter = afterTime;\n        } else {\n            this.startedAfter = afterTime;\n        }\n\n        return this;\n    }\n\n    @Override\n    public HistoricCaseInstanceQueryImpl startedBy(String userId) {\n        if (userId == null) {\n            throw new FlowableIllegalArgumentException(\"user id is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.startedBy = userId;\n        } else {\n            this.startedBy = userId;\n        }\n\n        return this;\n    }\n\n    @Override\n    public HistoricCaseInstanceQueryImpl finishedBy(String userId) {\n        if (userId == null) {\n            throw new FlowableIllegalArgumentException(\"user id is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.finishedBy = userId;\n        } else {","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java#L630-L666","documentation":"FlowableIllegalArgumentException thrown by HistoricCaseInstanceQueryImpl.startedBy(String) when the userId argument is null. The 'started by' filter is an identity restriction on the historic case instance initiator; a null identity is not a valid query criterion, so the library rejects it at build time.","triggerScenarios":"Calling createHistoricCaseInstanceQuery().startedBy(null); also occurs inside or() blocks since the null check precedes the inOrStatement branch.","commonSituations":"Passing the result of Authentication.getAuthenticatedUserId() (null for anonymous/unauthenticated contexts) into startedBy(); forwarding an optional 'userId' request parameter that was never provided.","solutions":["Pass a valid non-null userId string to startedBy().","If the user context may be anonymous, check for null and either skip the filter or throw a domain-level 'authentication required' error.","Validate request-supplied user identifiers before constructing the query."],"exampleFix":"// before\nquery.startedBy(Authentication.getAuthenticatedUserId()); // null when not logged in\n\n// after\nString userId = Authentication.getAuthenticatedUserId();\nif (userId != null) {\n    query.startedBy(userId);\n}","handlingStrategy":"validation","validationCode":"String userId = Authentication.getAuthenticatedUserId();\nif (userId != null) {\n    query.startedBy(userId);\n}","typeGuard":"boolean hasUserId(String userId) { return userId != null && !userId.trim().isEmpty(); }","tryCatchPattern":"try {\n    query.startedBy(userId);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"user id is null\")) {\n        throw new SecurityException(\"Cannot filter by initiator: no authenticated user\");\n    }\n    throw e;\n}","preventionTips":["Remember Authentication.getAuthenticatedUserId() returns null for anonymous contexts — always check it.","Validate request-supplied userId parameters (@NotBlank) before query building.","Decide explicitly whether a missing user means 'skip filter' or 'reject request' and encode that once in a helper."],"tags":["java","flowable","cmmn","null-check","query-builder"],"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"}