flowable/flowable-engine · warning · FlowableIllegalArgumentException
A group or a user is required to create an identity link.
Error message
A group or a user is required to create an identity link.
What it means
CaseDefinitionIdentityLinkCollectionResource.createIdentityLink adds an identity link (user or group) to a case definition from a JSON RestIdentityLink body. If neither 'group' nor 'user' is set in the body, the request is meaningless, so it throws FlowableIllegalArgumentException mapped to HTTP 400.
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/repository/CaseDefinitionIdentityLinkCollectionResource.java:74
return restResponseFactory.createRestIdentityLinks(repositoryService.getIdentityLinksForCaseDefinition(caseDefinition.getId()));
}
@ApiOperation(value = "Add a candidate starter to a case definition", tags = { "Case Definitions" },
notes = "It is possible to add either a user or a group.", code = 201)
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Indicates the case definition was found and the identity link was created."),
@ApiResponse(code = 400, message = "Indicates the body does not contain the correct information."),
@ApiResponse(code = 404, message = "Indicates the requested case definition was not found.")
})
@PostMapping(value = "/cmmn-repository/case-definitions/{caseDefinitionId}/identitylinks", produces = "application/json")
@ResponseStatus(HttpStatus.CREATED)
public RestIdentityLink createIdentityLink(@ApiParam(name = "caseDefinitionId") @PathVariable String caseDefinitionId, @RequestBody RestIdentityLink identityLink) {
CaseDefinition caseDefinition = getCaseDefinitionFromRequestWithoutAccessCheck(caseDefinitionId);
if (identityLink.getGroup() == null && identityLink.getUser() == null) {
throw new FlowableIllegalArgumentException("A group or a user is required to create an identity link.");
}
if (identityLink.getGroup() != null && identityLink.getUser() != null) {
throw new FlowableIllegalArgumentException("Only one of user or group can be used to create an identity link.");
}
if (restApiInterceptor != null) {
restApiInterceptor.createCaseDefinitionIdentityLink(caseDefinition, identityLink);
}
if (identityLink.getGroup() != null) {
repositoryService.addCandidateStarterGroup(caseDefinition.getId(), identityLink.getGroup());
} else {
repositoryService.addCandidateStarterUser(caseDefinition.getId(), identityLink.getUser());
}
// Always candidate for case definition. User-provided value is ignored
identityLink.setType(IdentityLinkType.CANDIDATE);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Include either "user":"<userId>" or "group":"<groupId>" in the request body.
- Check the JSON keys match RestIdentityLink field names exactly (user, group, type).
- Validate the payload client-side before posting the identity link.
Example fix
// before
POST .../identity-links
{"type":"candidate"}
// after
POST .../identity-links
{"type":"candidate","group":"sales"} Defensive patterns
Strategy: validation
Validate before calling
function validateIdentityLink(link) {
if (!link.user && !link.group) throw new Error('identity link needs user or group');
return true;
} Type guard
const isValidIdentityLink = (l) => Boolean(l && (typeof l.user === 'string' || typeof l.group === 'string'));
Try / catch
try {
await post(identityLinksUrl, link);
} catch (e) {
if (e.response?.status === 400 && /group or a user/.test(e.response.data?.message)) {
throw new Error('Request body must contain "user" or "group"');
}
throw e;
} Prevention
- Use field names 'user', 'group', 'type' exactly as RestIdentityLink expects.
- Validate payloads before POSTing identity links.
- Build payloads from typed models, not free-form objects.
When it happens
Trigger: POST /cmmn-repository/case-definitions/{caseDefinitionId}/identity-links with a body like {"type":"candidate"} lacking both 'user' and 'group' fields.
Common situations: Client sends only the link type; JSON property names mismatch the RestIdentityLink fields (e.g. 'userId' instead of 'user') so they deserialize to null; empty payloads from templated request builders.
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
- Only one of user or group can be used to create an identity
- User or group are required.
- Only one value of user or group is supported.
- The identity link type is required.
- Identity link family should be 'users' or 'groups'.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e84a24b4ba2020a0.
Report an issue: GitHub.