{"record":{"id":"cbbcee577de3e5ee","repo":"flowable/flowable-engine","slug":"a-group-or-a-user-is-required-to-create-an-identit-cbbcee","errorCode":null,"errorMessage":"A group or a user is required to create an identity link.","messagePattern":"A group or a user is required to create an identity link\\.","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskIdentityLinkCollectionResource.java","lineNumber":72,"sourceCode":"        }\n\n        return restResponseFactory.createRestIdentityLinks(taskService.getIdentityLinksForTask(task.getId()));\n    }\n\n    @ApiOperation(value = \"Create an identity link on a task\", tags = { \"Task Identity Links\" }, nickname = \"createTaskInstanceIdentityLinks\",\n            notes = \"It is possible to add either a user or a group.\", code = 201)\n    @ApiResponses(value = {\n            @ApiResponse(code = 201, message = \"Indicates the task was found and the identity link was created.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested task was not found or the task does not have the requested identityLink. The status contains additional information about this error.\")\n    })\n    @PostMapping(value = \"/cmmn-runtime/tasks/{taskId}/identitylinks\", produces = \"application/json\")\n    @ResponseStatus(HttpStatus.CREATED)\n    public RestIdentityLink createIdentityLink(@ApiParam(name = \"taskId\") @PathVariable(\"taskId\") String taskId, @RequestBody RestIdentityLink identityLink) {\n\n        Task task = getTaskFromRequestWithoutAccessCheck(taskId);\n\n        if (identityLink.getGroup() == null && identityLink.getUser() == null) {\n            throw new FlowableIllegalArgumentException(\"A group or a user is required to create an identity link.\");\n        }\n\n        if (identityLink.getGroup() != null && identityLink.getUser() != null) {\n            throw new FlowableIllegalArgumentException(\"Only one of user or group can be used to create an identity link.\");\n        }\n\n        if (identityLink.getType() == null) {\n            throw new FlowableIllegalArgumentException(\"The identity link type is required.\");\n        }\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.createTaskIdentityLink(task, identityLink);\n        }\n\n        if (identityLink.getGroup() != null) {\n            taskService.addGroupIdentityLink(task.getId(), identityLink.getGroup(), identityLink.getType());\n        } else {\n            taskService.addUserIdentityLink(task.getId(), identityLink.getUser(), identityLink.getType());","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskIdentityLinkCollectionResource.java#L54-L90","documentation":"Creating an identity link on a CMMN task requires at least one of 'group' or 'user' in the RestIdentityLink body. If both are null, createIdentityLink throws FlowableIllegalArgumentException because the link would have no target.","triggerScenarios":"POST /cmmn-runtime/tasks/{taskId}/identitylinks with a body containing only type (and maybe no user/group), or where user and group fields are omitted/null.","commonSituations":"Clients forgetting to set user or group; JSON field name mismatch (userId vs user); building links programmatically with only the type field populated.","solutions":["Set either the user or the group field in the RestIdentityLink request body","Check the JSON field names match RestIdentityLink properties (user, group, type)","Validate the body client-side before POSTing","Handle the 400 response from FlowableIllegalArgumentException by correcting the payload"],"exampleFix":"// before\n{\"type\":\"candidate\"}\n// after\n{\"type\":\"candidate\",\"user\":\"kermit\"}","handlingStrategy":"validation","validationCode":"if (!link.user && !link.group) throw new Error('A group or a user is required to create an identity link');","typeGuard":"const isLinkable = (l) => l != null && (typeof l.user === 'string' || typeof l.group === 'string');","tryCatchPattern":"try { await addIdentityLink(taskId, link); } catch (e) { if (e.message.includes('A group or a user is required')) { /* set user or group and retry */ } throw e; }","preventionTips":["Always populate user or group in identity link payloads","Validate RestIdentityLink fields before POST","Note the sibling rule: only one of user/group may be set"],"tags":["rest","identity-link","validation","missing-field"],"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-14T05:17:10.506Z"}