flowable/flowable-engine · error · FlowableException
CmmnRuntimeService cannot be null, Obtain your builder insta
Error message
CmmnRuntimeService cannot be null, Obtain your builder instance from the CmmnRuntimeService to access this feature
What it means
ChangePlanItemStateBuilderImpl.changeState() delegates to CmmnRuntimeService.changePlanItemState. The builder holds a reference to the runtime service injected at creation; if it is null (builder not obtained from CmmnRuntimeService, or manually constructed), the delegation cannot happen and a FlowableException is thrown.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/ChangePlanItemStateBuilderImpl.java:251
this.childInstanceTaskVariables.put(planItemDefinitionId, new HashMap<>());
}
this.childInstanceTaskVariables.get(planItemDefinitionId).put(name, value);
return this;
}
@Override
public ChangePlanItemStateBuilder childInstanceTaskVariables(String planItemDefinitionId, Map<String, Object> variables) {
if (!this.childInstanceTaskVariables.containsKey(planItemDefinitionId)) {
this.childInstanceTaskVariables.put(planItemDefinitionId, new HashMap<>());
}
this.childInstanceTaskVariables.get(planItemDefinitionId).putAll(variables);
return this;
}
@Override
public void changeState() {
if (runtimeService == null) {
throw new FlowableException("CmmnRuntimeService cannot be null, Obtain your builder instance from the CmmnRuntimeService to access this feature");
}
runtimeService.changePlanItemState(this);
}
public String getCaseInstanceId() {
return caseInstanceId;
}
public Set<ActivatePlanItemDefinitionMapping> getActivatePlanItemDefinitions() {
return activatePlanItemDefinitions;
}
public Set<MoveToAvailablePlanItemDefinitionMapping> getChangeToAvailableStatePlanItemDefinitions() {
return changeToAvailableStatePlanItemDefinitions;
}
public Set<TerminatePlanItemDefinitionMapping> getTerminatePlanItemDefinitions() {
return terminatePlanItemDefinitions;View on GitHub (pinned to d6d39ce1c6)
Solutions
- Obtain the builder via cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId) instead of instantiating it directly
- In tests, use the CmmnEngine/_process engine configuration to get a real CmmnRuntimeService
- If you must construct manually, inject the CmmnRuntimeService into the builder
Example fix
// before
ChangePlanItemStateBuilderImpl builder = new ChangePlanItemStateBuilderImpl();
builder.changeState(); // runtimeService is null
// after
ChangePlanItemStateBuilder builder = cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId);
builder.movePlanItemInstanceState("planItem1", "active").changeState(); Defensive patterns
Strategy: try-catch
Validate before calling
if (builder instanceof ChangePlanItemStateBuilderImpl) { /* ensure obtained via cmmnRuntimeService.createChangePlanItemStateBuilder */ } Type guard
boolean isServiceBacked(ChangePlanItemStateBuilder b) { return b != null && ((ChangePlanItemStateBuilderImpl) b).getRuntimeService() != null; } Try / catch
try { builder.changeState(); } catch (FlowableException e) { log.error("Builder not backed by CmmnRuntimeService: {}", e.getMessage()); } Prevention
- Always obtain the builder from CmmnRuntimeService.createChangePlanItemStateBuilder
- Never instantiate ChangePlanItemStateBuilderImpl directly in application or test code
- Inject the engine services rather than manual construction
When it happens
Trigger: Constructing ChangePlanItemStateBuilderImpl directly with new (no runtimeService), or deserializing/copying a builder across contexts, then calling changeState().
Common situations: Unit tests instantiating the builder directly; framework code wiring the builder without the runtime service; using the builder in a standalone environment without obtaining it from cmmnRuntimeService.createChangePlanItemStateBuilder().
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- batch has to be provided
- type has to be provided
- Setting variable is not supported for read only delegate exe
- Can only trigger a plan item that is in the ACTIVE state
- No External Worker job found for id: ${externalJobId}
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2d9d4e2507ee2158.
Report an issue: GitHub.