{"record":{"id":"2d9d4e2507ee2158","repo":"flowable/flowable-engine","slug":"cmmnruntimeservice-cannot-be-null-obtain-your-bui","errorCode":null,"errorMessage":"CmmnRuntimeService cannot be null, Obtain your builder instance from the CmmnRuntimeService to access this feature","messagePattern":"CmmnRuntimeService cannot be null, Obtain your builder instance from the CmmnRuntimeService to access this feature","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/ChangePlanItemStateBuilderImpl.java","lineNumber":251,"sourceCode":"            this.childInstanceTaskVariables.put(planItemDefinitionId, new HashMap<>());\n        }\n        this.childInstanceTaskVariables.get(planItemDefinitionId).put(name, value);\n        return this;\n    }\n\n    @Override\n    public ChangePlanItemStateBuilder childInstanceTaskVariables(String planItemDefinitionId, Map<String, Object> variables) {\n        if (!this.childInstanceTaskVariables.containsKey(planItemDefinitionId)) {\n            this.childInstanceTaskVariables.put(planItemDefinitionId, new HashMap<>());\n        }\n        this.childInstanceTaskVariables.get(planItemDefinitionId).putAll(variables);\n        return this;\n    }\n\n    @Override\n    public void changeState() {\n        if (runtimeService == null) {\n            throw new FlowableException(\"CmmnRuntimeService cannot be null, Obtain your builder instance from the CmmnRuntimeService to access this feature\");\n        }\n        runtimeService.changePlanItemState(this);\n    }\n\n    public String getCaseInstanceId() {\n        return caseInstanceId;\n    }\n\n    public Set<ActivatePlanItemDefinitionMapping> getActivatePlanItemDefinitions() {\n        return activatePlanItemDefinitions;\n    }\n\n    public Set<MoveToAvailablePlanItemDefinitionMapping> getChangeToAvailableStatePlanItemDefinitions() {\n        return changeToAvailableStatePlanItemDefinitions;\n    }\n\n    public Set<TerminatePlanItemDefinitionMapping> getTerminatePlanItemDefinitions() {\n        return terminatePlanItemDefinitions;","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/ChangePlanItemStateBuilderImpl.java#L233-L269","documentation":"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.","triggerScenarios":"Constructing ChangePlanItemStateBuilderImpl directly with new (no runtimeService), or deserializing/copying a builder across contexts, then calling changeState().","commonSituations":"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().","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"],"exampleFix":"// before\nChangePlanItemStateBuilderImpl builder = new ChangePlanItemStateBuilderImpl();\nbuilder.changeState(); // runtimeService is null\n// after\nChangePlanItemStateBuilder builder = cmmnRuntimeService.createChangePlanItemStateBuilder(caseInstanceId);\nbuilder.movePlanItemInstanceState(\"planItem1\", \"active\").changeState();","handlingStrategy":"try-catch","validationCode":"if (builder instanceof ChangePlanItemStateBuilderImpl) { /* ensure obtained via cmmnRuntimeService.createChangePlanItemStateBuilder */ }","typeGuard":"boolean isServiceBacked(ChangePlanItemStateBuilder b) { return b != null && ((ChangePlanItemStateBuilderImpl) b).getRuntimeService() != null; }","tryCatchPattern":"try { builder.changeState(); } catch (FlowableException e) { log.error(\"Builder not backed by CmmnRuntimeService: {}\", e.getMessage()); }","preventionTips":["Always obtain the builder from CmmnRuntimeService.createChangePlanItemStateBuilder","Never instantiate ChangePlanItemStateBuilderImpl directly in application or test code","Inject the engine services rather than manual construction"],"tags":["flowable","cmmn","builder","wiring","null"],"backgroundTag":"missing-required-config","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}