flowable/flowable-engine · error · UnsupportedOperationException
CommandInvoker must be the last interceptor in the chain
Error message
CommandInvoker must be the last interceptor in the chain
What it means
CmmnCommandInvoker.setNext() unconditionally throws UnsupportedOperationException because the command invoker must be the terminal interceptor of the command chain — nothing may come after it. This is a deliberate invariant-enforcement guard used while configuring the CMMN engine's interceptor stack.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/interceptor/CmmnCommandInvoker.java:208
}
agenda.planEvaluateCriteriaOperation(caseInstanceId, true);
}
involvedCaseInstanceIds.clear(); // Clearing after scheduling the evaluation. If anything changes, new operations will add ids again.
executeOperations(commandContext, false); // false -> here, we're past the regular operation loop. Any operation now that is a no-op should not reschedule a new evaluation
// If new involvedCaseInstanceIds have new entries, this means the evaluation has triggered new operations and data has changed.
// Need to retrigger the evaluations to make sure no new things can fire now.
if (!involvedCaseInstanceIds.isEmpty()) {
evaluateUntilStable(commandContext, allHandledCaseInstanceIds);
}
}
}
@Override
public void setNext(CommandInterceptor next) {
throw new UnsupportedOperationException("CommandInvoker must be the last interceptor in the chain");
}
public AgendaOperationRunner getAgendaOperationRunner() {
return agendaOperationRunner;
}
public void setAgendaOperationRunner(AgendaOperationRunner agendaOperationRunner) {
this.agendaOperationRunner = agendaOperationRunner;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Register CmmnCommandInvoker as the LAST interceptor: call setNext on preceding interceptors pointing toward the invoker, never setNext ON the invoker
- Use configuration defaults instead of manual chain wiring if possible
- Reorder your interceptor list so the invoker is at the end
Example fix
// before customInterceptor.setNext(commandInvoker); // throws: nothing after invoker // after commandInvoker.setNext(customInterceptor); // wrong direction too — instead: // beforeInterceptor.setNext(commandInvoker); // invoker must be last
Defensive patterns
Strategy: validation
Validate before calling
if (interceptor instanceof CmmnCommandInvoker) {
throw new IllegalStateException("CmmnCommandInvoker must be the last interceptor: never call setNext on it");
} Type guard
boolean isCommandInvoker(CommandInterceptor interceptor) {
return interceptor instanceof CmmnCommandInvoker;
} Try / catch
try {
previousInterceptor.setNext(invoker); // invoker as target, not as caller
} catch (UnsupportedOperationException e) {
// you tried to append after the invoker — reorder so the invoker is last
} Prevention
- Build the interceptor chain front-to-back, ending with CmmnCommandInvoker
- Never call setNext() on the command invoker instance
- Prefer relying on CmmnEngineConfiguration's default interceptor setup
When it happens
Trigger: Programmatically building a custom interceptor chain and calling setNext(cmmnCommandInvoker-like interceptor) with the CmmnCommandInvoker as the 'next' target, i.e. attempting to append an interceptor after the invoker.
Common situations: Custom CmmnEngineConfiguration interceptor setups; copying ProcessEngineConfiguration chain-building code to the CMMN engine and wiring the invoker in the wrong position.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Dmn engine is not configured
- To use the case service task a CaseInstanceService implement
- no org.flowable.app.engine.AppEngine defined in the applicat
- transactionManager is required property for SpringAppEngineC
- Setting a deployment name is not supported for apps
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/33c422fb7ece8007.
Report an issue: GitHub.