{"record":{"id":"b1257093c5402b37","repo":"flowable/flowable-engine","slug":"callbackids-is-null-or-empty-b12570","errorCode":null,"errorMessage":"callbackIds is null or empty","messagePattern":"callbackIds is null or empty","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/ProcessInstanceQueryImpl.java","lineNumber":784,"sourceCode":"            this.activeActivityIds = activityIds;\n        }\n        return this;\n    }\n\n    @Override\n    public ProcessInstanceQuery processInstanceCallbackId(String callbackId) {\n        if (inOrStatement) {\n            this.currentOrQueryObject.callbackId = callbackId;\n        } else {\n            this.callbackId = callbackId;\n        }\n        return this;\n    }\n\n    @Override\n    public ProcessInstanceQuery processInstanceCallbackIds(Set<String> callbackIds) {\n        if (callbackIds == null || callbackIds.isEmpty()) {\n            throw new FlowableIllegalArgumentException(\"callbackIds is null or empty\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.callbackIds = callbackIds;\n        } else {\n            this.callbackIds = callbackIds;\n        }\n        return this;\n    }\n    \n    @Override\n    public ProcessInstanceQuery processInstanceCallbackType(String callbackType) {\n        if (inOrStatement) {\n            this.currentOrQueryObject.callbackType = callbackType;\n        } else {\n            this.callbackType = callbackType;\n        }\n        return this;\n    }","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/ProcessInstanceQueryImpl.java#L766-L802","documentation":"ProcessInstanceQueryImpl.processInstanceCallbackIds(Set<String>) filters process instances by callback IDs (used with process/callback-type correlations). Flowable throws FlowableIllegalArgumentException when the set is null or empty because an empty IN clause is invalid SQL and the filter would be meaningless. The check runs in the query method itself.","triggerScenarios":"Calling processInstanceCallbackIds(null) or an empty set, typically when callback IDs were supplied by external callers (e.g., REST payloads) that contained none.","commonSituations":"REST/connector integration where the callback identifier list arrives empty from the client; business logic that only sometimes populates callback IDs but always applies the filter; copy-paste from processInstanceCallbackId (singular).","solutions":["Only call processInstanceCallbackIds when the set has at least one ID; otherwise skip the filter","Validate/sanitize the external input that supplies callback IDs before query construction","Use the singular processInstanceCallbackId(String) variant when there is exactly one ID","Catch FlowableIllegalArgumentException and respond with a clear client-side validation error"],"exampleFix":"// before\nquery.processInstanceCallbackIds(callbackIds); // may be empty\n// after\nif (callbackIds != null && !callbackIds.isEmpty()) {\n    query.processInstanceCallbackIds(callbackIds);\n} else {\n    throw new IllegalArgumentException(\"At least one callback id must be provided\");\n}","handlingStrategy":"validation","validationCode":"if (callbackIds == null || callbackIds.isEmpty()) {\n    throw new IllegalArgumentException(\"At least one callback id is required\");\n}","typeGuard":"boolean hasCallbackIds = callbackIds != null && !callbackIds.isEmpty();","tryCatchPattern":"try {\n    query.processInstanceCallbackIds(callbackIds);\n} catch (FlowableIllegalArgumentException e) {\n    // convert to client-side validation error\n}","preventionTips":["Validate external payloads supplying callback IDs before query construction","Use the singular processInstanceCallbackId(String) when only one ID exists","Never pass request-derived collections straight into Flowable filters"],"tags":["flowable","process-instance-query","empty-collection","callback-ids"],"backgroundTag":"empty-required-field","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"}