{"record":{"id":"f71fec4a86f778d1","repo":"flowable/flowable-engine","slug":"user-id-is-null-f71fec","errorCode":null,"errorMessage":"user id is null","messagePattern":"user id is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceQueryImpl.java","lineNumber":569,"sourceCode":"    }\n\n    @Override\n    public CaseInstanceQueryImpl caseInstanceStartedAfter(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        return this;\n    }\n\n    @Override\n    public CaseInstanceQueryImpl caseInstanceStartedBy(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        return this;\n    }\n    \n    @Override\n    public CaseInstanceQueryImpl caseInstanceState(String state) {\n        if (state == null) {\n            throw new FlowableIllegalArgumentException(\"state is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.state = state;\n        } else {\n            this.state = state;","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceQueryImpl.java#L551-L587","documentation":"Flowable throws this FlowableIllegalArgumentException when CaseInstanceQueryImpl.caseInstanceStartedBy(String) receives a null userId. The started-by filter matches the authenticated user that started the case; null is not accepted as a filter value so queries remain explicit.","triggerScenarios":"Calling caseInstanceQuery.caseInstanceStartedBy(null), often because SecurityUtils/Authentication returned no user (anonymous or system context) and that null was forwarded.","commonSituations":"Running queries from scheduled jobs or system threads without an authenticated user; passing getUserId() result straight into the query; migration code where the starter field is unknown.","solutions":["Pass a concrete user id string; for anonymous starts pass the documented empty/anonymous value if needed","Skip the startedBy filter when the starter is unknown","Resolve the current user with a fallback before building the query"],"exampleFix":"// before\nquery.caseInstanceStartedBy(securityManager.getAuthenticatedUserId()); // may be null\n// after\nString userId = securityManager.getAuthenticatedUserId();\nif (userId != null) {\n    query.caseInstanceStartedBy(userId);\n}","handlingStrategy":"validation","validationCode":"String userId = securityManager.getAuthenticatedUserId();\nif (userId != null) {\n    query.caseInstanceStartedBy(userId);\n}","typeGuard":"boolean hasAuthenticatedUser(Authentication a) { return a != null && a.getUserId() != null; }","tryCatchPattern":"try {\n    query.caseInstanceStartedBy(userId);\n} catch (FlowableIllegalArgumentException e) {\n    log.warn(\"No starter filter applied (no authenticated user): {}\", e.getMessage());\n}","preventionTips":["Always null-check the authenticated user id in system/scheduled contexts","Do not forward getUserId() results directly into query filters","Document that system queries should omit user filters rather than pass null"],"tags":["flowable","cmmn","null-argument","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-18T11:17:12.947Z"}