{"record":{"id":"bc8788a5d5b16c18","repo":"flowable/flowable-engine","slug":"batchsearchkey2-is-null","errorCode":null,"errorMessage":"batchSearchKey2 is null","messagePattern":"batchSearchKey2 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":130,"sourceCode":"            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\");\n        }\n        this.batchSearchKey = searchKey;\n        return this;\n    }\n\n    @Override\n    public BatchPartQuery batchSearchKey2(String searchKey2) {\n        if (searchKey2 == null) {\n            throw new FlowableIllegalArgumentException(\"batchSearchKey2 is null\");\n        }\n        this.batchSearchKey2 = searchKey2;\n        return this;\n    }\n\n    @Override\n    public BatchPartQuery status(String status) {\n        if (status == null) {\n            throw new FlowableIllegalArgumentException(\"status is null\");\n        }\n        this.status = status;\n        return this;\n    }\n\n    @Override\n    public BatchPartQuery scopeId(String scopeId) {\n        if (scopeId == null) {\n            throw new FlowableIllegalArgumentException(\"scopeId is null\");","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-batch-service/src/main/java/org/flowable/batch/service/impl/BatchPartQueryImpl.java#L112-L148","documentation":"BatchPartQueryImpl.batchSearchKey2(String) filters batch parts by the parent batch's secondary search key. Passing null throws FlowableIllegalArgumentException at the batchSearchKey2(...) call, mirroring all other null-filter guards in this query class. The error occurs before the query executes.","triggerScenarios":"Calling BatchPartQuery.batchSearchKey2(null), usually when the secondary batch search key is treated as optional upstream but passed unconditionally.","commonSituations":"Optional search criteria assumed to be nullable-safe; batches created without searchKey2; blank form inputs forwarded directly to the query.","solutions":["Null-check the value before calling batchSearchKey2(...).","Build the query conditionally, omitting the filter when the value is null.","If 'no secondary key' must be matched, query without the filter and post-filter in application code."],"exampleFix":"// before\nBatchPartQuery q = batchService.createBatchPartQuery().batchSearchKey(k1).batchSearchKey2(k2);\n// after\nBatchPartQuery q = batchService.createBatchPartQuery().batchSearchKey(k1);\nif (k2 != null) {\n    q.batchSearchKey2(k2);\n}","handlingStrategy":"validation","validationCode":"BatchPartQuery query = batchService.createBatchPartQuery().batchSearchKey(k1);\nif (k2 != null) {\n    query.batchSearchKey2(k2);\n}\nList<BatchPart> parts = query.list();","typeGuard":"boolean hasBatchSearchKey2(String k) {\n    return k != null && !k.isEmpty();\n}","tryCatchPattern":"try {\n    List<BatchPart> parts = query.batchSearchKey2(key).list();\n} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {\n    throw new IllegalArgumentException(\"batchSearchKey2 must not be null when filtering batch parts\", e);\n}","preventionTips":["Never pass null for optional filters; omit the filter call instead.","Centralize batch-part query construction so null-guards are applied uniformly."],"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-18T11:17:12.947Z"}