Understanding how sys_choice works on a list view with Domain SeparationDetailsMany a time, issues are raised on why certain choice labels are shown on list view for a field, where the choice is not present on the same domain as the session domain. The sys_choice table is a special table when in comes to domain separation. The mechanism how the labels are evaluated based on session domain is different in list and form. This article is going to help understand how the sys_choice works in list view. 1. The very first thing to remember is that, when in list view, it is the session domain that will be considered as the starting point of evaluating or finding the correct choice label. The behaviour is as expected. By design, lists are always using the user session's domain. Trying to follow each record's choice on the list would be confusing, for example in case incidents are in different domains, but we are using multi-row cell editing. This is documented in the below KB, present in the Additional information section. 2. Now, with this in mind, lets start with a use case, to understand how the choice label will be evaluated by the system. Imagine, We are on the sc_task table's list viewThe element 'State' present in that.The session domain is set as TOP/XYZ.There is only 1 record present in the list and the value for the state field is -5The instance has only one language setting, English(en)In the sys_choice table, for the state field on XYZ domain, no entry present for sc_task table, task tableAlso, in the same table no entry present for sc_task table, task table in global domain as well.However, there is an entry present against incident table with value as -5 and domain is global. Say the label is 'Incident State 5' With this scenario, if we open sc_task table list view, with state column and session domain as TOP/XYZ, the record with state value -5 will be showing label as 'Incident State 5'. Now we will deep dive why system is showing this label. Step 1: As per domain separation architecture on sys_choice table specifically, it will first try to look for the available choices on the sys_choice table based on (a) with the same domain as Session Domain, (b) name of the exact table in the list view , (c) name of the element (d) choice is active (inactive = false) (e) language based on logged in user's session Note that we are not taking into account the value of the field. Important thing is to first find the set of choices to pick the data from. Step 2: With the above conditions, in our scenario, when the system is trying to get the choice label, for the TOP/XYZ domain, with below conditions, it was not finding the one with value as -5 in the same domain as active,SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`name` = 'sc_task' AND sys_choice0.`element` = 'state' AND sys_choice0.`language` = 'en' AND sys_choice0.`sys_domain` = '12345678901234567890123456789012' AND (sys_choice0.`inactive` = 0 OR sys_choice0.`inactive` IS NULL ) ORDER BY sys_choice0.`sequence`,sys_choice0.`label`,sys_choice0.`dependent_value Step 3: If system does not find any record with this (which in this use case also), it will go a step above to check any choice is present on the Parent table of sc_task or not (with the same conditions like language, domain TOP/XYZ, field etc).SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`name` = 'task' AND sys_choice0.`element` = 'state' AND sys_choice0.`language` = 'en' AND sys_choice0.`sys_domain` = '12345678901234567890123456789012' Step 4: If system does not find any record with this (which in this use case also), system then checks for with the same conditions, but now on the Parent Domain (TOP), with table as task. SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`name` = 'task' AND sys_choice0.`element` = 'state' AND sys_choice0.`language` = 'en' AND sys_choice0.`sys_domain` = '774190f01f1310005a3637b8ec8b70ef' Step 5: If system does not find any record with this (which in this use case also), it goes to check in global domain. SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`name` = 'task' AND sys_choice0.`element` = 'state' AND sys_choice0.`language` = 'en' AND sys_choice0.`sys_domain` = 'global' Step 6: If system does not find any record with this (which in this use case also), then system expands it search for any child table's choices in the TOP/XYZ domain, which fits the condition. SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`element` = 'state' AND sys_choice0.`name` IN ('sn_ti_case' , 'u_sna_assumptions' , 'incident_task' , 'sa_error_handler_task' , 'sn_risk_response_task' , 'sn_risk_transfer_task' , 'sn_risk_avoidance_task' , 'sn_risk_acceptance_task' , 'sn_risk_mitigation_task' , 'std_change_proposal' , 'x_fstfs_service_ac_service_acceptance' .........<MULTIPLE CHILD TABLE OF TASKS>..............'sn_test_management_test_plan' , 'pm_project' , 'sn_audit_engagement' , 'sn_compliance_policy_exception' , 'rm_feature' , 'rm_doc' , 'rm_defect' , 'rm_test' , 'rm_enhancement' , 'rm_story' , 'sn_safe_story' , 'rm_epic' , 'sn_safe_epic' , 'sn_safe_feature' , 'itfm_dispute' , 'sc_req_item' , 'itfm_sb_stmt' , 'sn_customerservice_escalation') AND (sys_choice0.`sys_domain_path` = '/' OR sys_choice0.`sys_domain_path` LIKE '!!$/!!+/%' OR sys_choice0.`sys_domain_path` LIKE '!!$/!!1/!!W/!!./%' OR sys_choice0.`sys_domain_path` LIKE '!!$/!!$/!!&/!!!/%') GROUP BY sys_choice0.`name` ORDER BY sys_choice0.`name` Step 7 : Now, for each child table, system will repeat step 2, 4 and 5 (i.e. on XYZ domain, on TOP domain and then on global domain), it it finds some records matching the conditions. Note that, till now, none of the steps are checking for the value of the field. It is just looking for any choice record exists or not. Checking for the value will happen later. Now as we posited earlier, that we have entry on incident table, for this field on global domain, so below queries will be executed and at the last level it will find the data. (TOP/XYZ domain) SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`name` = 'incident' AND sys_choice0.`element` = 'state' AND sys_choice0.`language` = 'en' AND sys_choice0.`sys_domain` = '12345678901234567890123456789012' (TOP domain) SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`name` = 'incident' AND sys_choice0.`element` = 'state' AND sys_choice0.`language` = 'en' AND sys_choice0.`sys_domain` = '774190f01f1310005a3637b8ec8b70ef' (global domain) SELECT ... FROM sys_choice sys_choice0 WHERE sys_choice0.`name` = 'incident' AND sys_choice0.`element` = 'state' AND sys_choice0.`language` = 'en' AND sys_choice0.`sys_domain` = 'global' With this last query system will find some reference based on the conditions mentioned in the step 1, and then system will check for the values. If it finds a value, then it will show the Label. As we posited earlier that, there is an entry matching this condition with label as 'Incident State 5', hence for the record with state value as -5 will be showing this specific label. In case if it has failed here as well, then the value would have been shown in color blue, enclosed in brackets (like (-5) ) This is the way evaluation of label happens for sys_choice records for any fields on a list view. To see this enable debug SQL and analyze the session logs.Additional Informationhttps://hi.service-now.com/kb_view.do?sysparm_article=KB0685040