# Bidirectional multi-select field Jira \<\> Snow

**URL:** <https://community.exalate.com/t/bidirectional-multi-select-field-jira-snow/4780>\
**Category:** General Questions\
**Tags:** jira-cloud, servicenow, servicenow-jira, customfields, migrated\_question\
**Created:** [November 4, 2024, 7:23am UTC](https://community.exalate.com/t/bidirectional-multi-select-field-jira-snow/4780 "2024-11-04T07:23:27Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![xl8bot](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/xl8bot/32/324_2.png) [@xl8bot](https://community.exalate.com/u/xl8bot)\
**Post date:** [November 4, 2024, 7:23am UTC](https://community.exalate.com/t/bidirectional-multi-select-field-jira-snow/4780/1 "2024-11-04T07:23:27Z")

</div>

_Originally asked by Daniel Carvajal on 20 July 2021 [(original question)](https://oldcommunity.exalate.com/questions/30049809)_

* * *

Question raised by Enrique:

We have a multi-select list in both sides (Jira and SNOW), same options. We need bidirectional synchronization.  
I found how to do it Jira to Jira, but I didn’t found what replica.customFields.“MyField” = entity.multi\_select\_custom\_field would send.  
From other documentations it seems entity.multi\_select\_custom\_field will send the value, not a custom field object.  
Is there an example code in the documentation how to synchronize them?  
Thanks,

* * *

---

<div class="post-metadata">

**Author:** ![xl8bot](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/xl8bot/32/324_2.png) [@xl8bot](https://community.exalate.com/u/xl8bot)\
**Post date:** [November 4, 2024, 7:23am UTC](https://community.exalate.com/t/bidirectional-multi-select-field-jira-snow/4780/2 "2024-11-04T07:23:28Z")

</div>

_Answer by Enrique Cadalso on 10 August 2021_

This works

ServiceNow - Outgoing sync

```auto
replica.u_risk_type = entity.u_risk_type

```

ServiceNow - Incoming sync

```auto
entity.u_risk_type = replica.u_risk_type?.value?.collect{"${it.value}"}.join(",")

```

Jira - Outgoing sync

```auto
replica.u_risk_type = issue.customFields."Risk Type"

```

Jira - Incoming sync

```auto
issue.customFields."Risk Type"?.value = nodeHelper.getOptions(issue, "Risk Type", Arrays.asList(replica.u_risk_type?.split("\\s*,\\s*")))

```

* * *

---

<div class="post-metadata">

**Author:** ![xl8bot](https://dub1.discourse-cdn.com/flex018/user_avatar/community.exalate.com/xl8bot/32/324_2.png) [@xl8bot](https://community.exalate.com/u/xl8bot)\
**Post date:** [November 4, 2024, 7:23am UTC](https://community.exalate.com/t/bidirectional-multi-select-field-jira-snow/4780/3 "2024-11-04T07:23:28Z")

</div>

_Answer by Ariel Aguilar on 20 July 2021_

Hi there,

For example, if you have a multiselect(multiple choices) Custom Field in Jira side, and a “Risk Type” multi select choices in ServiceNow. You can try doing the following to make it bidirectional:

Jira to ServiceNow

Outgoing Jira:

```auto
replica.customFields."Risk Type" = issue.customFields."Risk Type"

```

Incoming SNOW:

```auto
if(entity.tableName == "incident") { 
    entity.u_risk_type = replica.customFields."Risk Type"?.value?.collect
{ opt -> opt?.value } ?: nodeHelper.getOptions(issue,"Risk Type",replica.customFields."Risk Type"?.value?.collect {it -> it?.value}) }

```

ServiceNow to Jira

Outgoing SNOW:

```auto
if(entity.tableName == "incident") {
    replica."Risk Type" = entity.u_risk_type
}

```

Incoming Jira:

```auto
issue.customFields."Risk Type"?.value = replica."Risk Type".collect
{ opt -> opt?.value } ?: nodeHelper.getOptions(issue,"Risk Type",replica."Risk Type"?.collect {it -> it?.value})

```

This worked for me. At the moment, we will work to add this to our documentation to make it a bit clear for everybody.

Kind regards,

Ariel

* * *

#### Comments:

> **Enrique Cadalso commented on 26 July 2021**
>
> > Hello,
> 
> I was asking for “multi-select list in both sides”. The provided example is for “multiselect(single choice) Custom Field in Jira side”.
> 
> I don’t think it will work like that.
> 
> Thanks,
> 
> Enrique

> **Ariel Aguilar commented on 26 July 2021**
>
> > Hi Enrique,
> 
> As you may know, both instances may have many and vary options. If the example is not working for this case, could you add the required name fields as shown on your instances. In this way, we won’t duplicate our efforts.
> 
> Thanks,
> 
> Ariel

> **Enrique Cadalso commented on 26 July 2021**
>
> > Hi Ariel,
> 
> Here you have the details.
> 
> In Servicenow there is a field type Multiple choice - multi selection that accept multiple values.
> 
> In Jira there is a field type Select List (multiple choices) that accept multiple values.
> 
> Both fields contain the same options so mapping is not required.
> 
> I need to know what is the syntax for the assignment in all sides.
> 
> | Servicenow Field Name | Servicenow Field type | Jira Field Name | Jira Field type |
> | --- | --- | --- | --- |
> | Risk Type (u\_risk\_type) | Multiple choice - multi selection **Options** \* Option1 \* Option2 \* Option2 | Risk Type (customfield\_21703) | Select List (multiple choices) **Options** \* Option1 \* Option2 \* Option2 |
> 
> Regards,
> 
> Enrique

> **Enrique Cadalso commented on 26 July 2021**
>
> > Using the provided code the error happens in Jira side. This is the error (anonymized )
> 
> ```auto
> Impact: ISSUE
> 
> Local entity: ETP-27
> 
> Remote entity: PRB0038185
> 
> Connection: Jira_to_ServiceNow
> 
> Error type: Sync rules result validation error.
> 
> Error Creation Time: 2021-07-26 10:44:41.742
> 
> Error Detail Message: Unexpected error occurred. The customfield `u_risk_type` was assigned to `value=[] class=java.util.ArrayList`, but it should have been set to a custom field object Generate an exalate support.zip file and contact support. Error Stack Trace: com.exalate.api.exception.bug.hubobjects.UnsupportedHubObjectsVersionBugException: Unexpected error occurred. The customfield `u_risk_type` was assigned to `value=[] class=java.util.ArrayList`, but it should have been set to a custom field object Generate an exalate support.zip file and contact support.
> at com.exalate.error.services.BugExceptionCategoryService.generateUnsupportedHubObjectsVersionBugException(BugExceptionCategoryService.scala:32)
> at com.exalate.hubobject.HubObjectValidator.checkCustomFieldConsistency(HubObjectValidator.java:96)
> at com.exalate.hubobject.HubObjectValidator.checkDataStructuresConsistency(HubObjectValidator.java:69)
> at com.exalate.hubobject.HubObjectValidator.validateIssueReplica(HubObjectValidator.java:54)
> at com.exalate.hubobject.v1_2.HubObjectHelper.validateReplica(HubObjectHelper.java:442)
> at com.exalate.processor.jira.JiraCreateReplicaProcessor.createHubReplica(JiraCreateReplicaProcessor.java:199)
> at com.exalate.processor.jira.JiraCreateReplicaProcessor.createHubReplica(JiraCreateReplicaProcessor.java:130)
> at com.exalate.replication.request.CreateReplicaSyncRequestState.transition(CreateReplicaSyncRequestState.java:139)
> at com.exalate.replication.request.CreateReplicaSyncRequestState.transition(CreateReplicaSyncRequestState.java:48)
> at com.exalate.replication.in.RequestProcessorService.processSyncRequest(RequestProcessorService.java:319)
> at com.exalate.replication.in.RequestProcessorService.processSyncRequestsForIssue(RequestProcessorService.java:189)
> at com.exalate.replication.in.RequestProcessorService.processSyncRequests(RequestProcessorService.java:126)
> at com.exalate.replication.in.RequestWorker$1.run(RequestWorker.java:91)
> at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.lambda$executeHandlingLocks$13(ClusteredSensitiveExecutorService.java:31)
> at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:46)
> at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:29)
> at com.exalate.replication.in.RequestWorker.run(RequestWorker.java:81)
> at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
> at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
> at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
> at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> at java.lang.Thread.run(Thread.java:748)
> Incoming sync data: Summary: Test snow ticket 01
> Entity Key: PRB0038185(id: undefined)
> Encoded payload: {
> "version": {
> "major": 1,
> "minor": 15,
> "patch": 0
> },
> "hubIssue": {
> ...
> "u_risk_type": "Option1, Option2",
> ...
> "internalMap": {
> ...
> "u_risk_type": "Option1, Option2",
> ...
> },
> ...
> },
> "issueUrl": " **********************"
> }
> 
> ```
> 
> Regards,
> 
> Enrique

> **Ariel Aguilar commented on 26 July 2021**
>
> > Hi Enrique,
> 
> I did some changes on the code I sent before, please take a look to update. Please be aware, I am not sure what “Multiple choice - multi selection” could be for ServiceNow. I have looked on their docs: [https://docs.servicenow.com/bundle/quebec-platform-administration/page/administer/reference-pages/reference/r\_FieldTypes.html](https://docs.servicenow.com/bundle/quebec-platform-administration/page/administer/reference-pages/reference/r_FieldTypes.html)  
> Either way, this might work for you. Just let me know.
> 
> Kind regards,
> 
> Ariel

> **Enrique Cadalso commented on 26 July 2021**
>
> > I get the same error.
> 
> When assigning values in Jira to a multi select field we are supposed to pass a collection of Option IDs. I was hoping Exalate would do the heavy lifting for me and I don’t have to iterate the values in “u\_risk\_type”: “Option1, Option2”, get the IDs and use some Jira Java API function to assign the values. In this case “Option1, Option2” are just strings. I don’t’ see square brackets so I wonder if they are interpreted as an array.
> 
> I am attaching in the screenshot how the field looks in the Servicenow UI, in case it helps. However, knowing what is received in the replica (included in the error) should be enough to know how to assign it to the Jira field.
> 
> Thanks,
> 
> Enrique
> 
> ![](https://dub1.discourse-cdn.com/flex018/download/thumbnails/30049809/image2021-7-26_15-12-41.png?version=1&modificationDate=1627326761804&api=v2)

> **Ariel Aguilar commented on 26 July 2021**
>
> > Hi Enrique,
> 
> I have modified both Jira and ServiceNow incoming sides one more time, let me know if that works for you.
> 
> Kind regards,
> 
> Ariel

> **Enrique Cadalso commented on 27 July 2021**
>
> > Using last version of the code error in Jira is:
> 
> ```auto
> Impact: RELATIONLocal entity: ETP-27Remote entity: PRB0038185Connection: JiraCloud_to_ServiceNowError type: Sync rules errorError Creation Time: 2021-07-27 12:51:55.113Error Detail Message: Wrong value type provided for custom field Risk Type(customfield_21703) Error Stack Trace: com.exalate.api.exception.script.ScriptException: Wrong value type provided for custom field Risk Type(customfield_21703)
> at com.exalate.error.services.ScriptExceptionCategoryService.categorizeProcessorAndIssueTrackerExceptionsIntoScriptExceptions(ScriptExceptionCategoryService.scala:34)
> at com.exalate.processor.jira.JiraChangeIssueProcessor.applyProcessorResult(JiraChangeIssueProcessor.java:314)
> at com.exalate.processor.jira.JiraChangeIssueProcessor.changeIssue(JiraChangeIssueProcessor.java:201)
> at com.exalate.replication.request.UpdateIssueSyncRequestState.transition(UpdateIssueSyncRequestState.java:118)
> at com.exalate.replication.request.UpdateIssueSyncRequestState.transition(UpdateIssueSyncRequestState.java:36)
> at com.exalate.replication.in.RequestProcessorService.processSyncRequest(RequestProcessorService.java:319)
> at com.exalate.replication.in.RequestProcessorService.processSyncRequestsForIssue(RequestProcessorService.java:189)
> at com.exalate.replication.in.RequestProcessorService.processSyncRequests(RequestProcessorService.java:126)
> at com.exalate.replication.in.RequestWorker$1.run(RequestWorker.java:91)
> at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.lambda$executeHandlingLocks$13(ClusteredSensitiveExecutorService.java:31)
> at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:46)
> at com.exalate.node.util.concurrent.ClusteredSensitiveExecutorService.executeHandlingLocks(ClusteredSensitiveExecutorService.java:29)
> at com.exalate.replication.in.RequestWorker.run(RequestWorker.java:81)
> at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
> at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
> at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
> at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
> at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> at java.lang.Thread.run(Thread.java:748)
> Caused by: java.lang.IllegalStateException: Wrong value type provided for custom field Risk Type(customfield_21703)
> at com.exalate.node.hubobject.v1_3.NodeHubObjectConversionService.getNodeOptions(NodeHubObjectConversionService.java:1659)
> at com.exalate.node.hubobject.v1_3.NodeHubObjectConversionService.getNodeCustomFieldValue(NodeHubObjectConversionService.java:1424)
> at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateCustomFieldWith(NodeHubIssueHelper.java:1378)
> at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateCustomFieldsWith(NodeHubIssueHelper.java:1357)
> at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.applyFields(NodeHubIssueHelper.java:1211)
> at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateIssueWith(NodeHubIssueHelper.java:854)
> at com.exalate.node.hubobject.v1_4.NodeHubIssueHelper.updateIssueWith(NodeHubIssueHelper.java:751)
> at com.exalate.compatibility.HubObjectHelperAdapter.updateNodeIssueWith(HubObjectHelperAdapter.java:61)
> at com.exalate.hubobject.v1_2.HubObjectHelper.updateNodeIssueWith(HubObjectHelper.java:352)
> at com.exalate.processor.jira.JiraChangeIssueProcessor.applyProcessorResult(JiraChangeIssueProcessor.java:311)
> ... 18 more
> Incoming sync data: Summary: Test snow ticket 01Entity Key: PRB0038185(id: undefined)Encoded payload: {
> "version": {
> "major": 1,
> "minor": 15,
> "patch": 0
> },
> "hubIssue": {
> ...
> "Risk Type": "Option1, Option2",
> ...
> "summary": "Test snow ticket 01",
> "comments": [],
> "internalMap": {
> ...
> "Risk Type": "Option1, Option2",
> ...
> },
> ...	},
> "issueUrl": " ************"
> }
> 
> ```
> 
> No errors on Servicenow but field is silently not populated:
> 
> The remote replica in Service now (data coming from Jira) is as follows
> 
> ```auto
> {
> "version": {
> "major": 1,
> "minor": 14,
> "patch": 0
> },
> "hubIssue": {
> ...
> "customFields": {
> "Risk Type": {
> "id": 21703,
> "name": "Risk Type",
> "uid": "21703",
> "type": "OPTIONS",
> "value": [
> {
> "id": "21909",
> "sequence": 1,
> "value": "Option1",
> "disabled": false,
> "childOptions": []
> },
> {
> "id": "21911",
> "sequence": 3,
> "value": "Option3",
> "disabled": false,
> "childOptions": []
> }
> ]
> }
> },
> "description": "Test snow ticket 01 description\r\nTest snow ticket 01 description2",
> ...
> "summary": "Test snow ticket 01",
> "comments": [],
> "internalMap": {
> ...
> },
> ...
> },
> "issueUrl": "https://jira ******* /browse/ETP-27"
> }
> 
> ```
