flowable/flowable-engine · error · FlowableIllegalArgumentException
The case instance id is mandatory, but
Error message
The case instance id is mandatory, but '${caseInstanceId}' has been provided. What it means
UpdateCaseInstanceCmd reads the case instance id from the CaseInstanceChangeUserStateBuilder and requires a non-empty value. A null or empty string is rejected with FlowableIllegalArgumentException, since the command cannot locate the case to modify without it.
Solutions
- Always call .caseInstanceId(id) on the builder with a non-blank id before starting the update.
- Validate the id in the calling layer (null/isEmpty check) and return a 400-style error early.
- Ensure the id originates from a successful CaseInstance lookup.
Example fix
// before
runtimeService.createCaseInstanceChangeUserStateBuilder().start(); // no caseInstanceId set
// after
runtimeService.createCaseInstanceChangeUserStateBuilder()
.caseInstanceId(caseInstanceId)
.businessKey(newBusinessKey)
.start(); Defensive patterns
Strategy: validation
Validate before calling
if (caseInstanceId == null || caseInstanceId.isEmpty()) {
throw new IllegalArgumentException("caseInstanceId is required for the update builder");
} Try / catch
try {
builder.start();
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("case instance id is mandatory")) {
// caller forgot .caseInstanceId(...)
}
} Prevention
- Always chain .caseInstanceId(id) immediately after createCaseInstanceChangeUserStateBuilder()
- Validate path/query parameters at the REST layer
- Write a test asserting the builder is fully populated
When it happens
Trigger: Calling cmmnRuntimeService.createCaseInstanceChangeUserStateBuilder() and starting the update without calling caseInstanceId(...), or calling it with an empty string.
Common situations: Copy-pasted builder code where the id line was dropped; an id variable that is null/empty after a failed lookup; REST layer forwarding an empty path parameter.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Cannot start case instance: no case instance builder…
- Cannot start case instance: no case instance builder…
- activatedBefore is null
- after time is null
- assignee is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f21fba532bf04ce1.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/UpdateCaseInstanceCmd.java:47
* {@link Command} that updates properties of an existing case instance.
*
* @author Tijs Rademakers
*/
public class UpdateCaseInstanceCmd implements Command<Void>, Serializable {
private static final long serialVersionUID = 1L;
protected CaseInstanceUpdateBuilderImpl builder;
public UpdateCaseInstanceCmd(CaseInstanceUpdateBuilderImpl builder) {
this.builder = builder;
}
@Override
public Void execute(CommandContext commandContext) {
String caseInstanceId = builder.getCaseInstanceId();
if (caseInstanceId == null || caseInstanceId.isEmpty()) {
throw new FlowableIllegalArgumentException("The case instance id is mandatory, but '" + caseInstanceId + "' has been provided.");
}
CaseInstanceEntityManager caseInstanceEntityManager = CommandContextUtil.getCaseInstanceEntityManager(commandContext);
CaseInstanceEntity caseInstanceEntity = caseInstanceEntityManager.findById(caseInstanceId);
if (caseInstanceEntity == null) {
throw new FlowableObjectNotFoundException("No case instance found for id = '" + caseInstanceId + "'.", CaseInstance.class);
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
if (builder.isBusinessKeySet()) {
caseInstanceEntityManager.updateCaseInstanceBusinessKey(caseInstanceEntity, builder.getBusinessKey());
}
if (builder.isBusinessStatusSet()) {
caseInstanceEntityManager.updateCaseInstanceBusinessStatus(caseInstanceEntity, builder.getBusinessStatus());
}
View on GitHub (pinned to d6d39ce1c6)