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

  1. Obtain the builder via cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId) instead of instantiating it directly
  2. In tests, use the CmmnEngine/_process engine configuration to get a real CmmnRuntimeService
  3. 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

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/2d9d4e2507ee2158. Report an issue: GitHub.