{"record":{"id":"463d46bcb952f93b","repo":"flowable/flowable-engine","slug":"searchkey2-is-null","errorCode":null,"errorMessage":"searchKey2 is null","messagePattern":"searchKey2 is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-batch-service/src/main/java/org/flowable/batch/service/impl/BatchPartQueryImpl.java","lineNumber":103,"sourceCode":"            throw new FlowableIllegalArgumentException(\"type is null\");\n        }\n        this.type = type;\n        return this;\n    }\n\n    @Override\n    public BatchPartQuery searchKey(String searchKey) {\n        if (searchKey == null) {\n            throw new FlowableIllegalArgumentException(\"searchKey is null\");\n        }\n        this.searchKey = searchKey;\n        return this;\n    }\n\n    @Override\n    public BatchPartQuery searchKey2(String searchKey2) {\n        if (searchKey2 == null) {\n            throw new FlowableIllegalArgumentException(\"searchKey2 is null\");\n        }\n        this.searchKey2 = searchKey2;\n        return this;\n    }\n\n    @Override\n    public BatchPartQuery batchType(String batchType) {\n        if (batchType == null) {\n            throw new FlowableIllegalArgumentException(\"batchType is null\");\n        }\n        this.batchType = batchType;\n        return this;\n    }\n\n    @Override\n    public BatchPartQuery batchSearchKey(String searchKey) {\n        if (searchKey == null) {\n            throw new FlowableIllegalArgumentException(\"batchSearchKey is null\");","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-batch-service/src/main/java/org/flowable/batch/service/impl/BatchPartQueryImpl.java#L85-L121","documentation":"BatchPartQueryImpl.searchKey2(String) filters batch parts by the secondary search key. Passing null throws FlowableIllegalArgumentException at the call site because a null filter is rejected rather than ignored. The check mirrors searchKey's validation.","triggerScenarios":"Calling BatchPartQuery.searchKey2(null), typically when the second search key is optional upstream but passed unconditionally into the query.","commonSituations":"Treating searchKey2 as optional: callers assume the query builder accepts null like an empty list() would; batches created without searchKey2 then queried by it; form fields left blank.","solutions":["Null-check the value before calling searchKey2(...).","Apply the filter conditionally — skip searchKey2(...) when the value is null.","If secondary key semantics require matching 'unset', query without the filter and post-filter results."],"exampleFix":"// before\nBatchPartQuery q = batchService.createBatchPartQuery().searchKey(k1).searchKey2(k2);\n// after\nBatchPartQuery q = batchService.createBatchPartQuery().searchKey(k1);\nif (k2 != null) {\n    q.searchKey2(k2);\n}","handlingStrategy":"validation","validationCode":"BatchPartQuery query = batchService.createBatchPartQuery().searchKey(k1);\nif (k2 != null) {\n    query.searchKey2(k2);\n}\nList<BatchPart> parts = query.list();","typeGuard":"boolean hasSearchKey2(String k) {\n    return k != null && !k.isEmpty();\n}","tryCatchPattern":"try {\n    List<BatchPart> parts = query.searchKey2(searchKey2).list();\n} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {\n    throw new IllegalArgumentException(\"searchKey2 must not be null when filtering batch parts\", e);\n}","preventionTips":["Apply optional secondary-key filters conditionally, never with null.","Keep filter-application logic in one helper to avoid inconsistent guards."],"tags":["flowable","batch","query","null-check"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}