flowable/flowable-engine · error · FlowableIllegalArgumentException
caseInstanceId is null
Error message
caseInstanceId is null
What it means
DeleteHistoricCaseInstanceCmd first validates that a caseInstanceId was supplied; a null value throws FlowableIllegalArgumentException("caseInstanceId is null"). The command exists to remove a historic case instance record, so an id is mandatory before any history lookup.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/DeleteHistoricCaseInstanceCmd.java:44
import org.flowable.common.engine.impl.interceptor.CommandContext;
/**
* @author Tijs Rademakers
*/
public class DeleteHistoricCaseInstanceCmd implements Command<Object>, Serializable {
private static final long serialVersionUID = 1L;
protected String caseInstanceId;
public DeleteHistoricCaseInstanceCmd(String caseInstanceId) {
this.caseInstanceId = caseInstanceId;
}
@Override
public Object execute(CommandContext commandContext) {
if (caseInstanceId == null) {
throw new FlowableIllegalArgumentException("caseInstanceId is null");
}
// Check if case instance is still running
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
HistoricCaseInstanceEntity instance = cmmnEngineConfiguration.getHistoricCaseInstanceEntityManager().findById(caseInstanceId);
if (instance == null) {
throw new FlowableObjectNotFoundException("No historic case instance found with id: " + caseInstanceId, HistoricCaseInstance.class);
}
if (instance.isDeleted()) {
return null;
}
if (instance.getEndTime() == null) {
throw new FlowableException("Case instance is still running, cannot delete " + instance);
}
cmmnEngineConfiguration.getCmmnHistoryManager().recordHistoricCaseInstanceDeleted(caseInstanceId, instance.getTenantId());View on GitHub (pinned to d6d39ce1c6)
Solutions
- Null-check (and emptiness-check) caseInstanceId before invoking the history service
- Fix the upstream source returning null ids (query result handling, entity mapping)
- Skip records without an id instead of calling the delete API for them
Example fix
// before
historyService.deleteHistoricCaseInstance(caseInstance.getId());
// after
if (caseInstance != null && caseInstance.getId() != null) {
historyService.deleteHistoricCaseInstance(caseInstance.getId());
} Defensive patterns
Strategy: validation
Validate before calling
if (caseInstanceId == null || caseInstanceId.isEmpty()) { throw new IllegalArgumentException("caseInstanceId required"); }
historyService.deleteHistoricCaseInstance(caseInstanceId); Type guard
boolean hasId(CaseInstance ci) { return ci != null && ci.getId() != null && !ci.getId().isEmpty(); } Try / catch
try { historyService.deleteHistoricCaseInstance(caseId); }
catch (FlowableIllegalArgumentException e) { if ("caseInstanceId is null".equals(e.getMessage())) { log.warn("skipped delete: null id"); } else throw e; } Prevention
- Null-check ids pulled from optional fields before deleting
- Skip entities without ids in batch cleanup loops
- Prefer querying historic instances first and using their ids
When it happens
Trigger: Calling CmmnHistoryService.deleteHistoricCaseInstance(null), e.g. when the id was read from an optional field or a query result that was empty.
Common situations: Iterating results where some entities expose null ids; unboxing from an Optional/getter chain returning null; batch cleanup scripts with unfiltered input.
Related errors
- Must specify a case instance id to migrate
- Must specify a case instance migration document to migrate
- Must specify a case definition id to migrate
- deploymentId is null
- query is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/47a208c1f08d834c.
Report an issue: GitHub.