What It Is
UI Policies dynamically control field behavior on forms by evaluating conditions and applying actions like making fields mandatory, read-only, or visible without requiring custom JavaScript. They solve the fundamental problem of static forms that can't adapt to different business scenarios—turning rigid form structures into intelligent interfaces that respond to user input and data context. Unlike Client Scripts that require coding expertise, UI Policies operate through a point-and-click interface that lets administrators define complex field interactions using conditions and actions.
Architecturally, UI Policies live in the System UI application within the UI Policies [sys_ui_policy] table, functioning at the presentation layer where they intercept form rendering and user interactions. They execute in the browser as client-side logic, generated from your declarative configuration into JavaScript that runs alongside the GlideForm API. Each UI Policy connects to specific tables through the Table field and affects forms, lists, and related records through inheritance and scoping rules.
The underlying execution model transforms your UI Policy configuration into Client Script equivalents that register with the form's onChange events and field watchers. ServiceNow automatically generates the necessary GlideForm calls (setMandatory(), setReadOnly(), setVisible()) based on your policy actions, creating a bridge between administrative configuration and technical implementation. This means UI Policies integrate seamlessly with existing Client Scripts and UI Actions, following the same form lifecycle and event handling patterns that govern all client-side form behavior.
You cannot function without UI Policies in scenarios where field requirements change based on data context—incidents that need different mandatory fields depending on priority, change requests with varying approval requirements based on risk, or user records where contact information becomes required only for external users. Any business process that demands "smart forms" that adapt to user selections, data values, or role-based requirements makes UI Policies essential infrastructure. Without them, you'd be writing dozens of individual Client Scripts to handle basic conditional field behavior, creating maintenance nightmares and inconsistent user experiences across your forms.
UI Policies are primarily managed by System Administrators and Application Administrators who need to control form behavior without coding skills, though Senior Developers often create more complex policies during application design phases. Platform Owners typically define governance around UI Policy usage, especially regarding performance impact when multiple policies affect the same form. The relationship flows from business requirements (defined by process owners) through administrative configuration (implemented by admins) to technical execution (generated by the platform), making UI Policies a critical bridge between business needs and technical delivery.
Recent ServiceNow releases have enhanced UI Policy performance through improved caching and reduced DOM manipulation, with Vancouver introducing better inheritance handling for extended tables and Xanadu optimizing policy evaluation order to reduce redundant field updates. The core functionality remains stable, but policy execution now batches field changes more efficiently, and the Policy Action framework supports additional field types like glide_date and reference fields more reliably than previous versions.
Where to Find and Configure It
Navigate to System UI > UI Policies for the primary configuration interface where you create, modify, and manage all UI Policies across your instance. Access System UI > UI Policy Actions to view and configure the specific field actions (mandatory, visible, read-only) that each policy applies. Use System Definition > Tables and drill into individual table records to see the UI Policies related list showing all policies affecting that specific table.
In Studio, find UI Policies under the User Interface section when developing scoped applications, where you can create application-specific policies that inherit your app's scope and namespace. App Engine Studio provides UI Policy creation through the Experience section under Form Experience for citizen developer scenarios. Check the sys_ui_policy table directly via System Definition > Tables & Columns when troubleshooting policy inheritance or bulk policy management.
See UI Policies in action on any form where they're configured—right-click and Inspect Element to view the generated JavaScript, or use Ctrl+Right-click and select Show UI Policies to see which policies are active on the current form. Global UI Policies apply across all applications and appear in Studio's dependency viewer, while scoped policies only affect records and forms within their specific application scope, creating clear boundaries for application-specific form behavior.
How It Works Step by Step
UI Policies operate through a two-phase execution model that transforms declarative configuration into runtime form behavior. During the form loading phase, ServiceNow evaluates all active UI Policies for the target table, converts their conditions and actions into JavaScript functions, and injects this generated code into the form's client-side environment. The system registers event handlers for fields referenced in policy conditions, creating a reactive system where field changes automatically trigger policy re-evaluation and field state updates.
The runtime execution phase activates when users interact with the form or when field values change programmatically. Each registered field change triggers the policy engine to evaluate conditions using current form values, determine which actions should apply, and execute the corresponding GlideForm API calls to update field states. This creates a cascading effect where one policy action might change a field value that triggers additional policy evaluations, continuing until all policies reach a stable state or hit the built-in recursion limits.
The policy evaluation engine maintains an execution context that tracks field dependencies, policy firing order, and state changes to prevent infinite loops and optimize performance. It uses a dirty-checking mechanism to avoid redundant field updates and batches multiple field changes into single DOM operations for better user experience.
Enjoying this? Get one deep-dive per week.
Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.
The Execution Order
- Form loads and triggers the UI Policy generator to query all active policies for the target table and its parent tables
- ServiceNow converts policy conditions into JavaScript conditional logic and policy actions into GlideForm API calls
- The system registers onChange handlers for all fields referenced in policy conditions, creating field watchers
- Initial policy evaluation runs using form's default/loaded field values to set initial field states
- User changes trigger field onChange events that execute associated policy conditions
- Policy engine evaluates conditions in order (Order field), executing actions for policies where conditions return true
- Field state changes (mandatory, visible, read-only) apply immediately through GlideForm API calls and DOM updates
- If field changes trigger additional policies, the cycle repeats until no more policies fire or recursion limits are reached
// Generated from UI Policy: "Priority-Based Field Requirements"
function evaluatePolicy_incident_priority_fields() {
var priority = g_form.getValue('priority');
// Condition: Priority is 1 or 2 (High/Critical)
if (priority == '1' || priority == '2') {
g_form.setMandatory('business_service', true);
g_form.setMandatory('cmdb_ci', true);
g_form.setVisible('impact_statement', true);
g_form.setReadOnly('assignment_group', false);
} else {
g_form.setMandatory('business_service', false);
g_form.setMandatory('cmdb_ci', false);
g_form.setVisible('impact_statement', false);
g_form.setReadOnly('assignment_group', true);
}
}
// Register onChange handler
g_form.onchange('priority', evaluatePolicy_incident_priority_fields);Real-World Scenarios
Dynamic Incident Fields Based on Priority and Category
High-priority incidents require additional detail fields that aren't needed for routine requests, while specific categories like Security or Network incidents need specialized fields that would clutter the form for other incident types. The business needs forms that adapt intelligently to show relevant fields without overwhelming agents with unnecessary options.
Create the UI Policy with Table set to 'Incident [incident]', set Conditions to 'Priority is one of 1-Critical, 2-High AND Category is one of Security, Network', then add Policy Actions for 'business_service' (Mandatory: true), 'security_notes' (Visible: true), and 'network_diagram' (Visible: true, Mandatory: true).
Watch for policy conflicts when multiple policies affect the same fields—use the Order field to control execution sequence and test policy interactions thoroughly. Consider performance impact on forms with many conditional fields, as each field change triggers all related policy evaluations. Set up proper field dependencies in your conditions to avoid policies firing unnecessarily when unrelated fields change.
Role-Based Field Access in User Records
External users and contractors need different contact information fields than internal employees, while certain sensitive fields should only be editable by HR administrators or remain read-only for self-service users. The user record form must dynamically adjust field visibility and editability based on the user's relationship to the organization and the current user's role permissions.
Create multiple UI Policies: one with Conditions 'User type is not Employee' making external contact fields mandatory and internal fields hidden, another with script condition 'gs.hasRole("hr_admin") == false' making salary and manager fields read-only, and a third for self-service users with Reverse if false checked to hide administrative fields entirely.
Test role-based policies thoroughly with different user accounts since policy evaluation happens client-side and role checks occur server-side through script conditions. Remember that Reverse if false checkbox inverts the policy logic, useful for "hide unless" scenarios. Monitor the Global checkbox setting since role-based policies often need global scope to function across different applications and modules.
Change Request Approval Requirements by Risk Level
Standard changes need minimal approval documentation while high-risk changes require detailed impact assessments, rollback plans, and multiple approver fields that would be excessive for routine changes. The change request form should progressively reveal complexity based on the calculated or selected risk level, guiding users toward appropriate detail levels.
Set up cascading UI Policies: first policy with Condition 'Risk is not Low' makes impact_assessment mandatory and shows rollback_plan field; second policy with Condition 'Risk is High OR Risk is Very High' adds mandatory fields for secondary_approver, business_justification, and downtime_window while making test_plan visible and mandatory.
Pay attention to calculated risk fields that might change after form load—use script conditions instead of simple field conditions if risk calculation depends on multiple field values. Consider the On Load checkbox for policies that should evaluate immediately when forms open rather than waiting for field changes. Test policy behavior with different change request workflows since approval field requirements might conflict with workflow stage transitions.
The Classic Mistake
Creating UI Policies with overlapping conditions that fight each other, causing fields to flicker between states or get stuck in the wrong state.
The classic scenario: You create one UI Policy with condition state == 'New' that makes the assigned_to field read-only. Then you create another UI Policy with condition assignment_group != '' that makes assigned_to visible and mandatory. Both policies have Active checked and apply to the same form. When a record is in New state and has an assignment group, both conditions are true simultaneously. The field becomes read-only AND mandatory, which is logically impossible. Users see the field grayed out but get mandatory field validation errors when they try to save.
ServiceNow processes UI Policies in order by the Order field, but when multiple policies affect the same field property, the last one wins for some properties (like read-only) while others accumulate (like mandatory). This creates unpredictable behavior because the DOM gets updated multiple times in rapid succession. The mandatory validation runs server-side but the read-only state is enforced client-side, creating a mismatch that confuses both users and developers.
// Single UI Policy condition that handles all scenarios
(state == 'New' && assignment_group == '') ||
(state == 'Work in Progress' && assigned_to != '') ||
(state == 'Resolved')
// UI Policy Actions:
// assigned_to: Visible = true, Mandatory = false, Read only = false
// Then create separate policies with mutually exclusive conditions:
// Policy 1: state == 'New' && assignment_group == ''
// Action: assigned_to Read only = true
// Policy 2: state == 'Work in Progress' && assignment_group != ''
// Action: assigned_to Mandatory = true
// Policy 3: state == 'Resolved'
// Action: assigned_to Read only = trueDesign UI Policies with mutually exclusive conditions. If two policies could both be true simultaneously and affect the same field, consolidate them into a single policy with a complex condition, or add exclusionary logic to make the conditions mutually exclusive.
When to Use This vs Alternatives
UI Policies are the right choice when you need to control field visibility, mandatory state, or read-only behavior based on other field values, and the logic is straightforward enough to be expressed in ServiceNow's condition builder. They excel at declarative field control that non-developers can understand and maintain.
Choose UI Policies When
Use UI Policies for simple field state changes based on current form values that can be expressed without scripting. They're perfect for scenarios like making fields mandatory when a certain category is selected, hiding irrelevant fields based on type selection, or making fields read-only after a workflow state change. Client Scripts can't match UI Policies for maintainability in these scenarios because the logic is visible in the condition builder rather than buried in code.
Use Client Scripts Instead When
Choose Client Scripts when you need complex logic that involves calculations, API calls, or DOM manipulation beyond basic field properties. UI Policies can't access GlideRecord queries, can't perform mathematical operations in conditions, and can't dynamically populate field options. If you need to validate complex business rules or integrate with external systems during form interaction, Client Scripts are your only option.
Use Both Together When
Combine UI Policies and Client Scripts when you have both simple declarative field control and complex business logic on the same form. Let UI Policies handle the straightforward field state management while Client Scripts handle data validation, calculations, and external integrations. This separation makes your form logic more maintainable and allows business analysts to modify the UI Policy conditions without touching code.
Platform Interactions & Side Effects
- ACLs override UI Policy field visibility—if an ACL denies read access, the field stays hidden regardless of UI Policy settings
- Business Rules executing
beforeinsert/update can conflict with UI Policy mandatory field enforcement, causing save operations to fail - Update Sets capture UI Policies in the
sys_ui_policyandsys_ui_policy_actiontables, but dependencies on choice lists and reference fields aren't automatically included - Mobile applications ignore UI Policies completely—field behavior must be controlled through Mobile UI Policies or the mobile-specific configuration
- Service Portal widgets don't automatically inherit UI Policies—the widget code must explicitly call
spUtil.getmethods to apply policy logic - Data Import ignores UI Policy mandatory field requirements—records can be imported with missing data that would be blocked on the form
- UI Policies create JavaScript functions cached in the user's browser session—clearing browser cache resolves most "policy not working" issues
- Workflow activities that auto-populate fields can trigger UI Policy evaluation, potentially overriding the workflow's field changes
- Performance impact: each UI Policy adds JavaScript to every form load—10+ policies on a single table can cause noticeable page load delays
- Clone operations bypass UI Policy enforcement during the cloning process but apply policies once the cloned record form loads
Debugging and Troubleshooting
The most common failure symptom is UI Policies that work inconsistently—they function correctly when you test them initially but fail under certain conditions or for specific users. Users report that fields aren't becoming mandatory when they should, or that fields remain hidden when they should be visible. Administrators often see UI Policies that appear to be configured correctly but simply don't trigger, especially after system updates or when multiple policies interact on the same form.
Start debugging by checking the browser's JavaScript console for errors—UI Policies generate client-side JavaScript that can fail silently. Navigate to System Logs > System Log > All and filter by Source: UI Policy to see server-side policy evaluation errors. Enable the glide.ui.policy.debug system property to log detailed policy execution information, including which policies are being evaluated and why they're succeeding or failing.
Common error messages include "Cannot read property of undefined" in browser console (indicating field references in conditions don't exist on the form), "UI Policy condition evaluation failed" in System Logs (pointing to syntax errors in advanced conditions), and "Policy not applied due to table inheritance conflict" when child tables have conflicting policies. Look for JavaScript errors containing "onChange" or "UIPolicy" in the browser developer tools, which indicate the policy's trigger mechanism is failing.
Diagnostic Checklist
- Verify the UI Policy's
Tablefield matches the form you're testing on—policies don't inherit up the table hierarchy - Check if all fields referenced in the condition are actually present on the form view being used
- Test the condition directly in a filter on the table to ensure it evaluates correctly with your test data
- Clear browser cache and hard refresh the form—UI Policy JavaScript is aggressively cached
- Confirm no ACLs are overriding the UI Policy by testing with admin role
- Review the
Orderfield on conflicting UI Policies—lower numbers execute first - Use the
Preview Script Usagerelated link to see the actual JavaScript generated by the policy
Quick Reference
- UI Policies only work on standard forms—they don't apply to List Edit, Import Sets, or custom Service Portal widgets
- Maximum of 25 UI Policy Actions per UI Policy—exceeding this limit causes the policy to be ignored completely
- Reference field conditions only evaluate the
sys_idvalue, not the display value—useassignment_group.namesyntax for display value comparisons - UI Policies on parent tables don't automatically apply to child tables—create separate policies or use
Globalscope - Date/time field conditions must account for user timezone—server-side conditions may evaluate differently than client-side display
- Choice field conditions are case-sensitive and must match the exact choice value, not the label displayed to users
- UI Policies with
Reverse if falseunchecked remain active even when conditions become false, requiring explicit reversal policies - Journal fields and HTML fields cannot be controlled by UI Policies—use Client Scripts for these field types
- Variable conditions in UI Policies use the variable name, not the variable label—check
item_option_newtable for exact variable names - UI Policies trigger on
onChangeevents—programmatic field changes via Client Scripts may not trigger policy re-evaluation without explicitonChange()calls