{"record":{"id":"bb9980d9a6425287","repo":"flowable/flowable-engine","slug":"type-is-required-when-deleting-a-process-identity-bb9980","errorCode":null,"errorMessage":"type is required when deleting a process identity link","messagePattern":"type is required when deleting a process identity link","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/DeleteIdentityLinkForProcessInstanceCmd.java","lineNumber":53,"sourceCode":"    protected String groupId;\n\n    protected String type;\n\n    public DeleteIdentityLinkForProcessInstanceCmd(String processInstanceId, String userId, String groupId, String type) {\n        validateParams(userId, groupId, processInstanceId, type);\n        this.processInstanceId = processInstanceId;\n        this.userId = userId;\n        this.groupId = groupId;\n        this.type = type;\n    }\n\n    protected void validateParams(String userId, String groupId, String processInstanceId, String type) {\n        if (processInstanceId == null) {\n            throw new ActivitiIllegalArgumentException(\"processInstanceId is null\");\n        }\n\n        if (type == null) {\n            throw new ActivitiIllegalArgumentException(\"type is required when deleting a process identity link\");\n        }\n\n        if (userId == null && groupId == null) {\n            throw new ActivitiIllegalArgumentException(\"userId and groupId cannot both be null\");\n        }\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        ExecutionEntity processInstance = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId);\n\n        if (processInstance == null) {\n            throw new ActivitiObjectNotFoundException(\"Cannot find process instance with id \" + processInstanceId, ExecutionEntity.class);\n        }\n\n        processInstance.deleteIdentityLink(userId, groupId, type);\n\n        commandContext.getHistoryManager().createProcessInstanceIdentityLinkComment(processInstanceId, userId, groupId, type, false);","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/DeleteIdentityLinkForProcessInstanceCmd.java#L35-L71","documentation":"DeleteIdentityLinkForProcessInstanceCmd requires an identity link type (e.g. \"candidate\", \"participant\") when deleting a process instance identity link; a null type is rejected with ActivitiIllegalArgumentException because the engine cannot determine which link kind to remove. It mirrors the IdentityLinkType constants used when links are added.","triggerScenarios":"Calling runtimeService.deleteProcessInstanceIdentityLink(processInstanceId, userId, groupId, null) — user/group supplied but the type argument is null.","commonSituations":"The link was created programmatically without a recorded type; callers copy the addIdentityLink call but drop the type parameter; or a wrapper method defaults the type to null.","solutions":["Pass the exact identity link type used when the link was added (IdentityLinkType constants like PARTICIPANT).","If the type is unknown, query runtimeService.getIdentityLinksForProcessInstance(processInstanceId) and use the returned link's getType().","Guard the type argument with a null check before the call."],"exampleFix":"// before\nruntimeService.deleteProcessInstanceIdentityLink(pid, userId, null, linkType); // linkType == null\n// after\nString linkType = link != null ? link.getType() : IdentityLinkType.PARTICIPANT;\nruntimeService.deleteProcessInstanceIdentityLink(pid, userId, null, linkType);","handlingStrategy":"validation","validationCode":"if (type == null) {\n    throw new IllegalArgumentException(\"Identity link type is required (see IdentityLinkType constants)\");\n}","typeGuard":"boolean hasLinkType(String type) { return type != null && !type.trim().isEmpty(); }","tryCatchPattern":"try {\n    runtimeService.deleteProcessInstanceIdentityLink(pid, userId, groupId, type);\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"type is required\")) {\n        throw new IllegalArgumentException(\"Supply the IdentityLinkType used when the link was added\", e);\n    }\n    throw e;\n}","preventionTips":["Use IdentityLinkType constants instead of raw strings or nullable variables.","Read the type back from getIdentityLinksForProcessInstance() when unknown locally.","Never default the type parameter to null in wrapper methods."],"tags":["null-argument","identity-link","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}