{"record":{"id":"d5e6d48ce90fb68a","repo":"flowable/flowable-engine","slug":"identityid-is-required-d5e6d4","errorCode":null,"errorMessage":"IdentityId is required.","messagePattern":"IdentityId is required\\.","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceIdentityLinkResource.java","lineNumber":103,"sourceCode":"\n        if (restApiInterceptor != null) {\n            restApiInterceptor.deleteProcessInstanceIdentityLink(processInstance, link);\n        }\n\n        if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family)) {\n            runtimeService.deleteGroupIdentityLink(processInstance.getId(), identityId, type);\n            \n        } else {\n            runtimeService.deleteUserIdentityLink(processInstance.getId(), identityId, type);\n        }\n    }\n\n    protected void validateIdentityLinkArguments(String family, String identityId, String type) {\n        if (family == null || (!RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && !RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family))) {\n            throw new FlowableIllegalArgumentException(\"Identity link family should be 'users' or 'groups'.\");\n        }\n        if (identityId == null) {\n            throw new FlowableIllegalArgumentException(\"IdentityId is required.\");\n        }\n        if (type == null) {\n            throw new FlowableIllegalArgumentException(\"Type is required.\");\n        }\n    }\n\n    protected IdentityLink getIdentityLink(String identityId, String family, String type, String processInstanceId) {\n        // Perhaps it would be better to offer getting a single identity link\n        // from the API\n        List<IdentityLink> allLinks = runtimeService.getIdentityLinksForProcessInstance(processInstanceId);\n        for (IdentityLink link : allLinks) {\n            if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_USERS.equals(family) && identityId.equals(link.getUserId()) && link.getType().equals(type)) {\n                return link;\n            \n            } else if (RestUrls.SEGMENT_IDENTITYLINKS_FAMILY_GROUPS.equals(family) && identityId.equals(link.getGroupId()) && link.getType().equals(type)) {\n                return link;\n            }\n        }","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ProcessInstanceIdentityLinkResource.java#L85-L121","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nString url = \"/runtime/process-instances/\" + pid + \"/identitylinks/users/\" + userId + \"/participant\";\n// after\nif (userId == null || userId.isEmpty()) throw new IllegalArgumentException(\"userId required\");\nString url = \"/runtime/process-instances/\" + pid + \"/identitylinks/users/\" + URLEncoder.encode(userId, UTF_8) + \"/participant\";","handlingStrategy":"validation","validationCode":"if (!userId) throw new Error('userId required before calling identity link endpoint');","typeGuard":"const hasIdentityId = (s) => typeof s === 'string' && s.length > 0;","tryCatchPattern":null,"preventionTips":["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"],"tags":["rest-api","validation","missing-argument"],"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-18T11:17:12.947Z"}