{"record":{"id":"2b47c0eefe85cf40","repo":"flowable/flowable-engine","slug":"historic-case-instanceids-are-empty","errorCode":null,"errorMessage":"historic case instanceIds are empty","messagePattern":"historic case instanceIds are empty","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":41,"sourceCode":"\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":23,"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#L23-L50","documentation":"BulkDeleteHistoricCaseInstancesCmd.execute throws FlowableIllegalArgumentException when the caseInstanceIds collection is non-null but empty. An empty batch is treated as a caller mistake (rather than a silent no-op) so users notice that their id selection produced nothing.","triggerScenarios":"Calling bulkDeleteHistoricCaseInstances with a zero-element list — e.g. a query for case instances closed before a date that matched nothing, or filtering that removed all ids before the call.","commonSituations":"Scheduled cleanup with over-aggressive date filters; UI passing an empty selection because no rows were checked; test fixtures with no historic data.","solutions":["Guard in caller code: skip the bulk delete when the id list is empty","Fix the selection/query that produced the empty batch if ids were expected","Treat empty input as no-op instead of calling the API"],"exampleFix":"// before\nhistoryService.bulkDeleteHistoricCaseInstances(ids);\n// after\nif (!ids.isEmpty()) {\n    historyService.bulkDeleteHistoricCaseInstances(ids);\n}","handlingStrategy":"validation","validationCode":"if (ids == null || ids.isEmpty()) { return; /* skip as no-op */ }","typeGuard":null,"tryCatchPattern":"try {\n    historyService.bulkDeleteHistoricCaseInstances(ids);\n} catch (FlowableIllegalArgumentException e) {\n    log.warn(\"Nothing to delete: {}\", e.getMessage());\n}","preventionTips":["Skip API calls with empty batches in scheduled jobs","Review selection filters that may legitimately produce zero ids","Log when an expected batch is empty so data issues surface early"],"tags":["flowable","cmmn","history","empty-collection"],"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-14T05:17:10.506Z"}