{"record":{"id":"2f0ec990724a4a24","repo":"flowable/flowable-engine","slug":"can-only-delete-a-child-entity-for-a-plan-item-wit","errorCode":null,"errorMessage":"Can only delete a child entity for a plan item with reference type ${referenceType} for ${delegatePlanItemInstance}","messagePattern":"Can only delete a child entity for a plan item with reference type (.+?) for (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/CaseTaskActivityBehavior.java","lineNumber":248,"sourceCode":"            if (caseInstance != null && !caseInstance.isDeleted()) {\n                CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n                cmmnEngineConfiguration.getCmmnHistoryManager().recordCaseInstanceEnd(\n                        caseInstance, CaseInstanceState.TERMINATED, cmmnEngineConfiguration.getClock().getCurrentTime());\n                caseInstanceEntityManager.delete(caseInstance.getId(), cascade, null);\n            }\n\n            // This is not the regular termination through the agenda, but the historic plan item state still needs to be correct.\n            // The child case instance needs to be deleted synchronously (not deferred via the agenda) to preserve entity link cleanup ordering.\n            PlanItemInstanceEntity planItemInstanceEntity = (PlanItemInstanceEntity) delegatePlanItemInstance;\n            if (!PlanItemInstanceState.TERMINATED.equals(planItemInstanceEntity.getState())) {\n                planItemInstanceEntity.setState(PlanItemInstanceState.TERMINATED);\n                planItemInstanceEntity.setEndedTime(CommandContextUtil.getCmmnEngineConfiguration(commandContext).getClock().getCurrentTime());\n                planItemInstanceEntity.setTerminatedTime(planItemInstanceEntity.getEndedTime());\n                CommandContextUtil.getCmmnHistoryManager(commandContext).recordPlanItemInstanceTerminated(planItemInstanceEntity);\n            }\n\n        } else {\n            throw new FlowableException(\"Can only delete a child entity for a plan item with reference type \" + ReferenceTypes.PLAN_ITEM_CHILD_CASE + \" for \" + delegatePlanItemInstance);\n        }\n    }\n\n    protected void handleOutParameters(CommandContext commandContext, PlanItemInstanceEntity planItemInstance) {\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        handleOutParameters(planItemInstance, cmmnEngineConfiguration);\n    }\n\n    protected void handleOutParameters(DelegatePlanItemInstance planItemInstance, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        if (outParameters == null) {\n            return;\n        }\n\n        CaseInstanceEntityManager caseInstanceEntityManager = cmmnEngineConfiguration.getCaseInstanceEntityManager();\n        CaseInstanceEntity referenceCase = caseInstanceEntityManager.findById(planItemInstance.getReferenceId());\n\n        IOParameterUtil.processOutParameters(outParameters, referenceCase, planItemInstance, cmmnEngineConfiguration.getExpressionManager());\n    }","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/CaseTaskActivityBehavior.java#L230-L266","documentation":"deleteChildEntity removes the child entity (child case instance) associated with a case task plan item and is only valid when the plan item's referenceType is PLAN_ITEM_CHILD_CASE. For any other reference type the method cannot know which child to delete and throws this error.","triggerScenarios":"Calling CaseTaskActivityBehavior.deleteChildEntity (via case task termination/exit handling) on a delegate plan item instance whose referenceType is not PLAN_ITEM_CHILD_CASE.","commonSituations":"Terminating a case task that never started a child case or was reused/misconfigured; custom code invoking deleteChildEntity directly; instance data migrated from another task type.","solutions":["Only invoke deleteChildEntity for case task plan items whose referenceType is PLAN_ITEM_CHILD_CASE and referenceId points at a live child case.","Verify the plan item configuration is a real case task with a valid case reference.","If terminating without a child, use the normal plan item termination path instead of child deletion.","Check for corrupted reference_type data in the ACT_CMMN_RU_PLAN_ITEM_INST table."],"exampleFix":"// before\nnew CaseTaskActivityBehavior().deleteChildEntity(commandContext, pii); // any plan item\n// after\nif (ReferenceTypes.PLAN_ITEM_CHILD_CASE.equals(pii.getReferenceType())) {\n    new CaseTaskActivityBehavior().deleteChildEntity(commandContext, pii);\n}","handlingStrategy":"validation","validationCode":"if (!ReferenceTypes.PLAN_ITEM_CHILD_CASE.equals(delegatePlanItemInstance.getReferenceType())) {\n    // use normal termination path instead of deleteChildEntity\n}","typeGuard":null,"tryCatchPattern":"try {\n    behavior.deleteChildEntity(commandContext, delegatePlanItemInstance);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"Can only delete a child entity\")) {\n        // fall back to planItem termination\n    }\n}","preventionTips":["Call deleteChildEntity only for plan items with referenceType PLAN_ITEM_CHILD_CASE","Use the standard termination APIs for other plan item types","Verify case task configuration points at a real child case","Check runtime table integrity after migrations"],"tags":["cmmn","case-task","child-case","reference-type"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}