UI Policy Mandatory Fields Triggering Too Early & Preventing State Transition on Problem Task

LEELAVENKAK
Tera Contributor

Hi all,
I’m trying to make Close notes and Cause code mandatory only when the Problem Task state is in "Work in Progress".

To achieve this, I created both a UI Policy and a Data Policy.
However, I’m running into an issue:

  • As soon as I click Start Work, the state changes to Work in Progress.
  • Immediately, the mandatory UI policy triggers (as expected), BUT…
  • The state transition doesn’t complete — the record stays stuck in the Assess state.
  • The mandatory field warning blocks the transition before the system updates the state on the form.

I’ve attached a screenshot for reference showing the error banner appearing before the state actually updates.

Has anyone faced this issue? How can I enforce mandatory fields after the state transition, without blocking the change from Assess → Work in Progress?

Any guidance would be appreciated!

2 REPLIES 2

ChallaR
Giga Guru

Hi @LEELAVENKAK 

you're running into a classic UI Policy timing issue in ServiceNow:

  • When you click Start Work, the client-side value of state flips to “Work in Progress” immediately, so your UI Policy turns Close notes and Cause code mandatory before the form actually submits.
  • The platform then checks mandatory fields and blocks the submit, so the record never leaves Assess—it gets stuck with the banner you showed.

please find the below recommendations  and steps -

 

Recommendation-

1) Don’t make them mandatory in WIP via UI Policy

  • Use a UI Policy only to show (and optionally make editable) the fields in WIP.
  • Do not set them mandatory in WIP using a UI Policy—that’s what is blocking the submit.

Why: UI Policies evaluate on the client as soon as the field value changes, before the record is saved. That’s perfect for display and enable/disable, but not for a “must be filled before you leave WIP” requirement.

2) Enforce the requirement when leaving WIP (e.g., going to Closed)

Pick one of these two enforcement points (you can do both if you want belt‑and‑suspenders):

Option A — OnSubmit Client Script (only when moving to Closed or out of WIP)

  • Scope it so it only runs when the user is submitting a transition out of WIP (e.g., “Close”).
  • This keeps the “Start Work” experience smooth and enforces the fields at the right moment.
function onSubmit() {
  // Replace with your actual choice values
  var STATE_WIP = '2';     // example
  var STATE_CLOSED = '3';  // example

  var newState = g_form.getValue('state');
  var closeNotes = g_form.getValue('close_notes');   // update field name as needed
  var causeCode  = g_form.getValue('u_cause_code');  // update field name as needed

  // Only enforce when going to Closed (or any state != WIP, adapt to your process)
  if (newState == STATE_CLOSED) {
    if (!closeNotes || !causeCode) {
      g_form.addErrorMessage('Close notes and Cause code are required to close this task.');
      // Optionally highlight fields:
      g_form.showFieldMsg('close_notes', 'Required', 'error', true);
      g_form.showFieldMsg('u_cause_code', 'Required', 'error', true);
      return false; // block submit
    }
  }
  return true;
}
``

Option B — Server-side Before Business Rule (authoritative, regardless of UI)

  • Guarantees the rule is enforced even via API/imports.
  • Checks state change and rejects the update if fields aren’t filled.

Example (Business Rule → Before, on Update):

(function executeRule(current, previous /*null when async*/) {
  // Replace with your actual values
  var STATE_WIP = 2;     
  var STATE_CLOSED = 3;  

  // Enforce when transitioning *from* WIP *to* Closed (or more broadly, when leaving WIP)
  var leavingWip = (previous.state == STATE_WIP) && (current.state != STATE_WIP);

  // If your requirement is only for Closed, use: current.state == STATE_CLOSED
  if (leavingWip) {
    if (gs.nil(current.close_notes) || gs.nil(current.u_cause_code)) {
      gs.addErrorMessage('Close notes and Cause code are required before leaving Work in Progress.');
      current.setAbortAction(true);
    }
  }
})(current, previous);
``

 

3) (Optional) UI Action logic for “Close” button

If users transition via a Close UI Action, put the validation there. That avoids global onSubmit logic and keeps validation tied to the transition button.

Example (UI Action → Client script):

// Condition: show when state == WIP
// Onclick (Client) script:
function onClick() {
  var closeNotes = g_form.getValue('close_notes');
  var causeCode  = g_form.getValue('u_cause_code');

  if (!closeNotes || !causeCode) {
    g_form.addErrorMessage('Close notes and Cause code are required to close this task.');
    g_form.showFieldMsg('close_notes', 'Required', 'error', true);
    g_form.showFieldMsg('u_cause_code', 'Required', 'error', true);
    return false;
  }

  // Set the state to Closed and submit via action name
  g_form.setValue('state', '3'); // replace with your Closed value
  gsftSubmit(null, g_form.getFormElement(), 'close_task'); // action name
  return false; // prevent default submit
}
``

 

above u have mentioned 3 options you can use it accordingly as per Ur  requirement .

 

Thanks,

Rithika.ch

 

Ankur Bawiskar
Tera Patron

@LEELAVENKAK 

My thoughts:

-> keep Data policy for server side validation

-> use onchange client script on state field to make mandatory

function onChange(control, oldValue, newValue, isLoading) {

    if (isLoading || newValue == '')
        return;
		
    if (newValue == '2') { // Work in Progress (confirm choice value)
        g_form.setMandatory('close_notes', true);
        g_form.setMandatory('cause_code', true);
        g_form.addErrorMessage('Close notes and Cause code are required for Work in Progress.');
    } else {
        g_form.setMandatory('close_notes', false);
        g_form.setMandatory('cause_code', false);
    }
}

💡 If my response helped, please mark it as correct and close the thread 🔒— this helps future readers find the solution faster! 🙏

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader