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

  1. Always call .caseInstanceId(id) on the builder with a non-blank id before starting the update.
  2. Validate the id in the calling layer (null/isEmpty check) and return a 400-style error early.
  3. 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

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


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)