{"record":{"id":"7995cc6c15bc54af","repo":"flowable/flowable-engine","slug":"historic-case-instanceids-are-null","errorCode":null,"errorMessage":"historic case instanceIds are null","messagePattern":"historic case instanceIds are null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/BulkDeleteHistoricCaseInstancesCmd.java","lineNumber":37,"sourceCode":"import org.flowable.cmmn.engine.impl.util.CommandContextUtil;\nimport org.flowable.common.engine.api.FlowableIllegalArgumentException;\nimport org.flowable.common.engine.impl.interceptor.Command;\nimport org.flowable.common.engine.impl.interceptor.CommandContext;\n\npublic class BulkDeleteHistoricCaseInstancesCmd implements Command<Object>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n\n    protected Collection<String> caseInstanceIds;\n\n    public BulkDeleteHistoricCaseInstancesCmd(Collection<String> caseInstanceIds) {\n        this.caseInstanceIds = caseInstanceIds;\n    }\n\n    @Override\n    public Object execute(CommandContext commandContext) {\n        if (caseInstanceIds == null) {\n            throw new FlowableIllegalArgumentException(\"historic case instanceIds are null\");\n        }\n\n        if (caseInstanceIds.isEmpty()) {\n            throw new FlowableIllegalArgumentException(\"historic case instanceIds are empty\");\n        }\n        \n        CommandContextUtil.getCmmnHistoryManager(commandContext).recordBulkDeleteHistoricCaseInstances(caseInstanceIds);\n        \n        return null;\n    }\n\n}\n","sourceCodeStart":19,"sourceCodeEnd":50,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/BulkDeleteHistoricCaseInstancesCmd.java#L19-L50","documentation":"BulkDeleteHistoricCaseInstancesCmd.execute throws FlowableIllegalArgumentException when the historic caseInstanceIds collection is null. The command records a bulk historic delete via the CmmnHistoryManager and needs a real collection to iterate; null input is rejected immediately.","triggerScenarios":"Calling cmmnHistoryService.bulkDeleteHistoricCaseInstances(null) or constructing the command with a null id collection, typically from an unguarded upstream lookup returning null.","commonSituations":"History cleanup jobs passing a null batch of ids after an empty query; REST payloads omitting the ids array so it binds to null; copying code from BulkDeleteCaseInstancesCmd assumptions.","solutions":["Pass a non-null collection of historic case instance ids","Default null to an empty list at the call site","Check the upstream id-query result and skip the bulk delete when nothing matched"],"exampleFix":"// before\nhistoryService.bulkDeleteHistoricCaseInstances(historicIds);\n// after\nhistoryService.bulkDeleteHistoricCaseInstances(historicIds != null ? historicIds : Collections.emptyList());","handlingStrategy":"type-guard","validationCode":"if (historicIds == null) historicIds = Collections.emptyList();","typeGuard":"boolean isNonNullCollection(Collection<?> c) { return c != null; }","tryCatchPattern":"try {\n    historyService.bulkDeleteHistoricCaseInstances(ids);\n} catch (FlowableIllegalArgumentException e) {\n    log.error(\"Bulk historic delete rejected: {}\", e.getMessage());\n}","preventionTips":["Initialize id collections eagerly instead of leaving fields null","Guard history-cleanup jobs against null query results","Bind REST ids arrays with a default empty list"],"tags":["flowable","cmmn","history","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-14T05:17:10.506Z"}