Interested in a ServiceNow event built for developers? Registration for now[dev]26 is officially open!

RITM is not getting approved even the inbound email action got processed

Hemagiri B
Tera Expert

When I try to approve the RITM through email, the Inbound Email Action is being processed successfully, but the RITM approval state is not changing to “Approved” and remains in “Requested” state.

We are using the OOB Inbound Email Action “Update Approval Request.” As shown in the logs below, after the OOB code executes current.update();, we are getting a null result:

[Approval Email Debug] Update result: null

Could someone please check and help us identify the root cause of why the approval record is not being updated to “Approved”?

 

current.comments = "reply from: " + email.from + "\n\n" + email.body_text;
var controller = new GlideController();
controller.putGlobal("approvalSource", "email");
current.update();
 
Logs as follow
 
HemagiriB_0-1788838415671.png

 

18 REPLIES 18

Hi Hemagiri,

 

Thanks for running that. Two notes before the useful part - most of what you pasted is noise, and there are two things buried in it that change the picture.

 

On "Unable to find vtable operation for operation id {}" - ignore those. That is not your script. It comes from the MIF vtable framework and it is a known post-clone issue (PRB2040054): sn_mif_vtable_operation is excluded from clones but sn_mif_vtable_operation_context is not, so the context table is left holding references to operation records that no longer exist, and every script execution logs those lines. Unrelated to the approval. One exception worth checking: if this approval is driven by a Flow rather than the classic workflow, that PRB can genuinely affect Flow Designer execution - let me know which one you are on.

 

Now the part that matters. Strip the vtable lines out and your log reads:

 

Slow business rule 'Reduce request price - approval change' on sysapproval_approver - 0:00:00.314

ApiUserRestUtils.getData statusCode:200 -> /api/now/table/sys_user

*** Script: {"result":[]}

Slack approval message BR: Slack approval message at update RITM BR

ERROR: RITM0112754 / B Hemagiri / NIL channel: no thrown error

Slow business rule 'Slack approval message at update RITM' on sysapproval_approver - 0:00:00.869

 

Three things follow from that.

 

1. There are custom business rules on sysapproval_approver. Earlier you mentioned there were none - the platform is naming two of them here, on that exact table, against RITM0112754: "Reduce request price - approval change" and "Slack approval message at update RITM". Both are logged as slow business rules, so both ran during the update we are testing.

 

2. The Slack one is failing. It calls out to /api/now/table/sys_user and /api/now/table/oauth_credential, gets HTTP 200 back with an empty {"result":[]}, cannot resolve a channel, and logs "NIL channel: no thrown error". That phrasing is your own script's, which means there is a try/catch in there swallowing whatever actually went wrong.

 

3. It is making synchronous outbound REST inside a business rule on the approval record - hence the 0.869s. A callout in the update path is a very common cause of exactly what you are seeing: update() returns null, nothing throws, and the record does not move.

 

Separately: one of those REST URLs points at https://watsondev.service-now.com. If that is not the instance you are working in, the credential and endpoint config came across in a clone and is pointing somewhere it should not - which would explain the empty result sets on both lookups.

 

Two things that would close this out:

 

1. Open "Slack approval message at update RITM" and check when it runs (before or after update), and whether anywhere in it - including the catch block - there is a current.setAbortAction(true), a current.update(), or an early return that leaves the record untouched. Same quick look at "Reduce request price - approval change".

2. Re-run the background script, but this time paste just the gs.info output - the line that prints the result and getLastErrorMessage(). That did not come through; everything in your paste is session log rather than the script's own return value. That one line tells us whether the write was aborted and by what.

 

Fast test in the meantime: deactivate "Slack approval message at update RITM", then reply to the approval email again. If it approves, we have found it.

 

If this analysis helps you get to the fix, I would appreciate you recommending the effort and marking it as the preferred solution - it helps me keep supporting these deep-dive issues properly, and it makes it much easier for the next person hitting the same silent approval failure to find a resolved answer in the Community.

 

Macki | Deloitte AU | Engineer Lead

Macki | Deloitte AU | Engineer Lead

@musislam ,
I will check the above and let you know.

@Hemagiri B 

 

Let me know the update.

Macki | Deloitte AU | Engineer Lead

@musislam ,

 

The issue has been fixed. We identified a new Business Rule named “Check approval state change”, which was introduced as part of the Australia upgrade.

This Business Rule was aborting the approval record update, which caused the approvals to remain in the “Requested” state.

After disabling this Business Rule, the approval process is working as expected.

Hi Hemagiri,

Good find, and thanks for coming back with the answer. The Slack rule I pointed at wasn't the cause, but the mechanism was the same: a rule stops the update, so update() returns null and nothing errors.

One thing worth knowing: I checked a clean Australia Patch 3 PDI, and there's no business rule called "Check approval state change" on the approval table. So confirm where yours came from before you decide what to do with it.

Before your next upgrade:

  1. Find where it came from. Open the rule and check Application, Created by and the dates. Then look for it in the upgrade log (sys_upgrade_history_log) for your Australia upgrade. If it's there, a plugin or store app shipped it. If not, someone added it as a customisation.
  2. Find out why it blocks, rather than just leaving it off. Read its condition and the code that calls setAbortAction(true). If it only lets the approver or a delegate change the state, check the User on the inbound email record. If the sender's email address doesn't match the approver's user record, the fix is the user record, not the rule.
  3. If it's ServiceNow's own code, raise a Now Support case. A platform rule blocking the standard "Update Approval Request" action looks like a defect.
  4. Write down that you turned it off. Deactivating a platform rule counts as a customisation, so the next upgrade will list it as Skipped in the upgrade log. Review it there and choose to keep or revert it, so it doesn't stay off unnoticed.
  5. Add a regression test. Build an ATF test that submits an RITM, uses the "Generate Inbound Reply Email" step to reply "approve", then checks that the approval and the RITM both show Approved. Run it in sub-prod after every patch and upgrade.

If that helps, mind marking it as the recommended solution? Helps me support these better for the community.

Macki | Deloitte AU | Engineer Lead