{"record":{"id":"a25c8702a248a738","repo":"flowable/flowable-engine","slug":"must-specify-a-historic-case-instance-id-to-migrat","errorCode":null,"errorMessage":"Must specify a historic case instance id to migrate","messagePattern":"Must specify a historic case instance id to migrate","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/HistoricCaseInstanceMigrationCmd.java","lineNumber":38,"sourceCode":"import org.flowable.common.engine.impl.interceptor.Command;\nimport org.flowable.common.engine.impl.interceptor.CommandContext;\n\npublic class HistoricCaseInstanceMigrationCmd implements Command<Void> {\n    \n    protected CmmnEngineConfiguration cmmnEngineConfiguration;\n\n    protected String caseInstanceId;\n    protected String caseDefinitionId;\n    protected String caseDefinitionKey;\n    protected int caseDefinitionVersion;\n    protected String caseDefinitionTenantId;\n    protected HistoricCaseInstanceMigrationDocument historicCaseInstanceMigrationDocument;\n\n    public HistoricCaseInstanceMigrationCmd(String caseInstanceId, HistoricCaseInstanceMigrationDocument historicCaseInstanceMigrationDocument,\n            CmmnEngineConfiguration cmmnEngineConfiguration) {\n        \n        if (caseInstanceId == null) {\n            throw new FlowableException(\"Must specify a historic case instance id to migrate\");\n        }\n        if (historicCaseInstanceMigrationDocument == null) {\n            throw new FlowableException(\"Must specify a historic case instance migration document to migrate\");\n        }\n        \n        this.caseInstanceId = caseInstanceId;\n        this.historicCaseInstanceMigrationDocument = historicCaseInstanceMigrationDocument;\n        this.cmmnEngineConfiguration = cmmnEngineConfiguration;\n    }\n\n    public HistoricCaseInstanceMigrationCmd(HistoricCaseInstanceMigrationDocument historicCaseInstanceMigrationDocument, String caseDefinitionId,\n            CmmnEngineConfiguration cmmnEngineConfiguration) {\n        \n        if (caseDefinitionId == null) {\n            throw new FlowableException(\"Must specify a case definition id to migrate\");\n        }\n        if (historicCaseInstanceMigrationDocument == null) {\n            throw new FlowableException(\"Must specify a historic case instance migration document to migrate\");","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/HistoricCaseInstanceMigrationCmd.java#L20-L56","documentation":"HistoricCaseInstanceMigrationCmd migrates a single historic case instance, so its constructor requires the caseInstanceId. When it is null the command throws FlowableException immediately: without an instance id there is nothing to migrate and no sensible lookup can be performed.","triggerScenarios":"Calling new HistoricCaseInstanceMigrationCmd(null, migrationDocument, cmmnEngineConfiguration) — e.g. the instance id came from a query that returned no row, a UI selection that was never populated, or HistoricCaseInstanceQuery.singleResult() returned null.","commonSituations":"Migrating after a lookup on a wrong engine/datasource so the id resolved to null; passing the runtime (non-historic) variable that was never set; batch jobs iterating over an empty result list and defaulting the id to null.","solutions":["Obtain a valid historic case instance id via cmmnHistoryService.createHistoricCaseInstanceQuery().caseDefinitionKey(...)...singleResult().getId() before constructing the command.","Null-check the id at the call site and skip/error per instance rather than passing null into the command.","Confirm you are querying the same CMMN engine configuration/database that contains the historic instances."],"exampleFix":"// before\nHistoricCaseInstance instance = query.singleResult(); // may be null\nnew HistoricCaseInstanceMigrationCmd(instance != null ? instance.getId() : null, doc, cfg);\n\n// after\nHistoricCaseInstance instance = query.singleResult();\nif (instance == null) throw new IllegalStateException(\"No historic case instance found\");\nnew HistoricCaseInstanceMigrationCmd(instance.getId(), doc, cfg);","handlingStrategy":"validation","validationCode":"if (caseInstanceId == null || caseInstanceId.isBlank())\n    throw new IllegalArgumentException(\"caseInstanceId required for historic case migration\");\nHistoricCaseInstance hci = historyService.createHistoricCaseInstanceQuery()\n    .caseInstanceId(caseInstanceId).singleResult();\nif (hci == null) throw new IllegalArgumentException(\"Unknown historic case instance: \" + caseInstanceId);","typeGuard":"boolean isValidInstanceId(String id) { return id != null && !id.isBlank(); }","tryCatchPattern":"try {\n    execute(new HistoricCaseInstanceMigrationCmd(caseInstanceId, doc, cfg));\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"case instance id\")) {\n        throw new IllegalArgumentException(\"Resolve the historic case instance id before migrating\", e);\n    }\n    throw e;\n}","preventionTips":["Query the historic instance and check singleResult() != null before migrating","Skip (not null-pass) instances missing from lookups in batch scripts","Ensure you query the same engine/datasource the instances live in"],"tags":["flowable","cmmn","null-argument","case-migration","history"],"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"}