flowable/flowable-engine · error · ActivitiIllegalArgumentException
type is required when deleting a process identity link
Error message
type is required when deleting a process identity link
What it means
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.
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.
Example fix
// before runtimeService.deleteProcessInstanceIdentityLink(pid, userId, null, linkType); // linkType == null // after String linkType = link != null ? link.getType() : IdentityLinkType.PARTICIPANT; runtimeService.deleteProcessInstanceIdentityLink(pid, userId, null, linkType);
Defensive patterns
Strategy: validation
Validate before calling
if (type == null) {
throw new IllegalArgumentException("Identity link type is required (see IdentityLinkType constants)");
} Type guard
boolean hasLinkType(String type) { return type != null && !type.trim().isEmpty(); } Try / catch
try {
runtimeService.deleteProcessInstanceIdentityLink(pid, userId, groupId, type);
} catch (ActivitiIllegalArgumentException e) {
if (e.getMessage().contains("type is required")) {
throw new IllegalArgumentException("Supply the IdentityLinkType used when the link was added", e);
}
throw e;
} Prevention
- 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.
When it happens
Trigger: Calling runtimeService.deleteProcessInstanceIdentityLink(processInstanceId, userId, groupId, null) — user/group supplied but the type argument is null.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- appDefinitionId is null
- identityId is null
- identityId is null
- processDefinitionId is null
- processDefinitionId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/bb9980d9a6425287.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/DeleteIdentityLinkForProcessInstanceCmd.java:53
protected String groupId;
protected String type;
public DeleteIdentityLinkForProcessInstanceCmd(String processInstanceId, String userId, String groupId, String type) {
validateParams(userId, groupId, processInstanceId, type);
this.processInstanceId = processInstanceId;
this.userId = userId;
this.groupId = groupId;
this.type = type;
}
protected void validateParams(String userId, String groupId, String processInstanceId, String type) {
if (processInstanceId == null) {
throw new ActivitiIllegalArgumentException("processInstanceId is null");
}
if (type == null) {
throw new ActivitiIllegalArgumentException("type is required when deleting a process identity link");
}
if (userId == null && groupId == null) {
throw new ActivitiIllegalArgumentException("userId and groupId cannot both be null");
}
}
@Override
public Void execute(CommandContext commandContext) {
ExecutionEntity processInstance = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId);
if (processInstance == null) {
throw new ActivitiObjectNotFoundException("Cannot find process instance with id " + processInstanceId, ExecutionEntity.class);
}
processInstance.deleteIdentityLink(userId, groupId, type);
commandContext.getHistoryManager().createProcessInstanceIdentityLinkComment(processInstanceId, userId, groupId, type, false);View on GitHub (pinned to d6d39ce1c6)