flowable/flowable-engine · error · FlowableIllegalArgumentException
IdentityId is required.
Error message
IdentityId is required.
What it means
Flowable REST throws FlowableIllegalArgumentException when validating identity link arguments on a process instance. The identityId path segment (user or group id) was null/absent when resolving the identity link URL. The REST API requires family, identityId, and type segments to look up or delete an identity link.
Solutions
- Ensure the identityId path segment is non-empty in the request URL.
- Validate the user/group id variable before building the URL client-side.
- Use URL templates/encoders instead of string concatenation to avoid empty segments.
Example fix
// before
String url = "/runtime/process-instances/" + pid + "/identitylinks/users/" + userId + "/participant";
// after
if (userId == null || userId.isEmpty()) throw new IllegalArgumentException("userId required");
String url = "/runtime/process-instances/" + pid + "/identitylinks/users/" + URLEncoder.encode(userId, UTF_8) + "/participant"; Defensive patterns
Strategy: validation
Validate before calling
if (!userId) throw new Error('userId required before calling identity link endpoint'); Type guard
const hasIdentityId = (s) => typeof s === 'string' && s.length > 0;
Prevention
- Use URL builder helpers that reject empty path segments
- Log the fully-built URL when requests fail
- Validate user/group ids at the source of the workflow
When it happens
Trigger: DELETE or GET to /runtime/process-instances/{id}/identitylinks/users/{identityId}/{type} or /groups/{identityId}/{type} with an empty or missing {identityId} path segment, e.g. .../identitylinks/users//participant.
Common situations: URL built by string concatenation with an uninitialized user/group variable; client template placeholders ({userId}) not filled in; trailing path manipulation accidentally removing the segment.
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
- IdentityId is required.
- Type is required.
- Type is required.
- A group or a user is required to create an identity link.
- A request body was expected when executing the form submit.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d5e6d48ce90fb68a.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceIdentityLinkResource.java:103
if (restApiInterceptor != null) {
restApiInterceptor.deleteProcessInstanceIdentityLink(processInstance, link);
}
if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family)) {
runtimeService.deleteGroupIdentityLink(processInstance.getId(), identityId, type);
} else {
runtimeService.deleteUserIdentityLink(processInstance.getId(), identityId, type);
}
}
protected void validateIdentityLinkArguments(String family, String identityId, String type) {
if (family == null || (!RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && !RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family))) {
throw new FlowableIllegalArgumentException("Identity link family should be 'users' or 'groups'.");
}
if (identityId == null) {
throw new FlowableIllegalArgumentException("IdentityId is required.");
}
if (type == null) {
throw new FlowableIllegalArgumentException("Type is required.");
}
}
protected IdentityLink getIdentityLink(String identityId, String family, String type, String processInstanceId) {
// Perhaps it would be better to offer getting a single identity link
// from the API
List<IdentityLink> allLinks = runtimeService.getIdentityLinksForProcessInstance(processInstanceId);
for (IdentityLink link : allLinks) {
if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family) && identityId.equals(link.getUserId()) && link.getType().equals(type)) {
return link;
} else if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && identityId.equals(link.getGroupId()) && link.getType().equals(type)) {
return link;
}
}View on GitHub (pinned to d6d39ce1c6)