{"record":{"id":"fde13c2442619413","repo":"flowable/flowable-engine","slug":"the-identity-link-type-is-required-fde13c","errorCode":null,"errorMessage":"The identity link type is required.","messagePattern":"The identity link type is required\\.","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceIdentityLinkCollectionResource.java","lineNumber":84,"sourceCode":"            @ApiResponse(code = 400, message = \"Indicates the requested body did not contain a userId or a type.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested process instance was not found.\")\n    })\n    @PostMapping(value = \"/runtime/process-instances/{processInstanceId}/identitylinks\", produces = \"application/json\")\n    @ResponseStatus(HttpStatus.CREATED)\n    public RestIdentityLink createIdentityLink(@ApiParam(name = \"processInstanceId\") @PathVariable String processInstanceId, @RequestBody RestIdentityLink identityLink) {\n\n        ProcessInstance processInstance = getProcessInstanceFromRequestWithoutAccessCheck(processInstanceId);\n\n        if (identityLink.getGroup() == null && identityLink.getUser() == null) {\n            throw new FlowableIllegalArgumentException(\"User or group are required.\");\n        }\n        \n        if (StringUtils.isEmpty(identityLink.getGroup()) && StringUtils.isEmpty(identityLink.getUser())) {\n            throw new FlowableIllegalArgumentException(\"Only one value of user or group is supported.\");\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.createProcessInstanceIdentityLink(processInstance, identityLink);\n        }\n\n        if (StringUtils.isNotEmpty(identityLink.getGroup())) {\n            runtimeService.addGroupIdentityLink(processInstance.getId(), identityLink.getGroup(), identityLink.getType());\n            \n        } else {\n            runtimeService.addUserIdentityLink(processInstance.getId(), identityLink.getUser(), identityLink.getType());\n        }\n\n        return restResponseFactory.createRestIdentityLink(identityLink.getType(), identityLink.getUser(), identityLink.getGroup(), null, null, processInstance.getId());\n    }\n}\n","sourceCodeStart":66,"sourceCodeEnd":101,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceIdentityLinkCollectionResource.java#L66-L101","documentation":"Every identity link must have a type (e.g. 'participant', 'candidate', 'starter', or a custom type). If the type field is null in the request body, createIdentityLink throws FlowableIllegalArgumentException('The identity link type is required.') since Flowable cannot categorize the link.","triggerScenarios":"POST /runtime/process-instances/{id}/identitylinks with {\"user\":\"kermit\"} — body lacks \"type\". Thrown at ProcessInstanceIdentityLinkCollectionResource.java:84.","commonSituations":"Assuming the API defaults the type to 'participant' (it does not); DTO field name mismatch (\"linkType\" vs \"type\"); JSON serializers omitting the field when unset.","solutions":["Add \"type\" to the body with a valid identity link type, e.g. {\"type\":\"participant\",\"user\":\"kermit\"}.","Fix DTO/JSON key mapping so the type value actually serializes under \"type\".","Consult the identity link types (GET /identity/link types or docs) and pick the right one for your use case."],"exampleFix":"// before\n{\"user\":\"kermit\"}\n// after\n{\"type\":\"participant\",\"user\":\"kermit\"}","handlingStrategy":"validation","validationCode":"if (link.getType() == null || link.getType().isEmpty()) {\n    throw new IllegalArgumentException(\"Identity link 'type' is required (e.g. participant)\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    restClient.createIdentityLink(instanceId, link);\n} catch (HttpClientErrorException.BadRequest e) {\n    if (e.getResponseBodyAsString().contains(\"identity link type is required\")) {\n        // set type and retry\n    }\n}","preventionTips":["Default the type in your client wrapper (e.g. to 'participant') when unset.","Keep a whitelist of valid identity link types.","Ensure the DTO field serializes under the key \"type\"."],"tags":["rest-api","identity-link","validation","java"],"backgroundTag":"empty-required-field","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"}