{"record":{"id":"d0a0fba4cbccd7c9","repo":"flowable/flowable-engine","slug":"type-is-required-when-adding-a-new-process-instanc","errorCode":null,"errorMessage":"type is required when adding a new process instance identity link","messagePattern":"type is required when adding a new process instance identity link","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AddIdentityLinkForProcessInstanceCmd.java","lineNumber":59,"sourceCode":"\n    protected String type;\n\n    public AddIdentityLinkForProcessInstanceCmd(String processInstanceId, String userId, String groupId, String type) {\n        validateParams(processInstanceId, userId, groupId, type);\n        this.processInstanceId = processInstanceId;\n        this.userId = userId;\n        this.groupId = groupId;\n        this.type = type;\n    }\n\n    protected void validateParams(String processInstanceId, String userId, String groupId, String type) {\n\n        if (processInstanceId == null) {\n            throw new FlowableIllegalArgumentException(\"processInstanceId is null\");\n        }\n\n        if (type == null) {\n            throw new FlowableIllegalArgumentException(\"type is required when adding a new process instance identity link\");\n        }\n\n        if (userId == null && groupId == null) {\n            throw new FlowableIllegalArgumentException(\"userId and groupId cannot both be null\");\n        }\n\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n\n        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);\n        ExecutionEntity processInstance = executionEntityManager.findById(processInstanceId);\n\n        if (processInstance == null) {\n            throw new FlowableObjectNotFoundException(\"Cannot find process instance with id \" + processInstanceId, ExecutionEntity.class);\n        }\n","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AddIdentityLinkForProcessInstanceCmd.java#L41-L77","documentation":"FlowableIllegalArgumentException thrown by AddIdentityLinkForProcessInstanceCmd.validateParams when the identity link 'type' argument is null. Identity links (assignee, candidate, starter, custom types) require a type to record what kind of relation is being attached to the process instance. The command refuses to run without it.","triggerScenarios":"Calling RuntimeService.addUserIdentityLink(processInstanceId, userId, type), addGroupIdentityLink, or addParticipantStart/addIdentityLinkForProcessInstance with a null 'type' argument while processInstanceId and userId/groupId are provided.","commonSituations":"Building the type string dynamically (e.g. from a variable or config lookup) and getting null; passing null for custom link types; mapping code that omits the type field from a DTO; upgrading code that previously called a convenience method that defaulted the type.","solutions":["Pass a non-null identity link type, e.g. IdentityLinkType.ASSIGNEE, IdentityLinkType.CANDIDATE, or a custom string.","If the type comes from config/data, add a null check or default value before invoking the runtime service call.","Validate input at the API/DTO layer so the type is required before reaching the Flowable command."],"exampleFix":"// before\nruntimeService.addUserIdentityLink(processInstanceId, userId, linkType); // linkType is null\n// after\nString linkType = type != null ? type : IdentityLinkType.PARTICIPANT;\nruntimeService.addUserIdentityLink(processInstanceId, userId, linkType);","handlingStrategy":"validation","validationCode":"if (linkType == null || linkType.isEmpty()) {\n    throw new IllegalArgumentException(\"identity link type is required\");\n}","typeGuard":"boolean hasType(String t) { return t != null && !t.trim().isEmpty(); }","tryCatchPattern":"try {\n    runtimeService.addUserIdentityLink(piId, userId, linkType);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"type is required\")) {\n        // fix: supply a valid IdentityLinkType\n    }\n    throw e;\n}","preventionTips":["Always pass a constant from IdentityLinkType instead of an ad-hoc string variable.","Validate link type at the service/DTO boundary before invoking the runtime service.","Add unit tests covering null-type input to identity-link helpers."],"tags":["flowable","identity-link","null-argument","validation"],"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-14T11:17:12.474Z"}