onAfter transform script with target.update() triggers insert / update business rule twice

Max Nowak
Kilo Sage

Hi,

 

I have an onAfter transform map script that updates a value on the target record after it has been inserted. To do that, I call target.update() in the transform script.

 

Is this effectively the same as calling current.update() in an "after" business rule? Because it seems to cause some unintended behaviour with Business Rules.

 

For example, I have a BR that triggers on Insert / Update of a record, and it only triggers when a certain field changes (current.fieldName.changes() in condition). When the transform map runs and inserts a record, the BR is triggered, as expected, as the field changes from null to something. Immediately afterwards though, the record is updated through the onAfter transform script, and surprisingly, fieldName.changes() still evaluates to true for that update, even though the field did not change.

3 REPLIES 3

James Chun
Kilo Patron

Hi @Max Nowak,

 

A few things to note:

  • Is it possible to update the target update with the onBefore script? This would prevent a BR from being executed more than once.
  • Can you share the onAfter transform script and BR's configuration? In case you are not aware, using current.update() in a BR is a bad practice as it can end up in a recursive loop.

Cheers

Hi James,

Thanks for your reply. The reality is that the onAfter transform script was implemented by the customer's internal ServiceNow team, and while I can possibly nudge them in the right direction, it's ultimately not my decision.

 

I won't be able to share the exact scripts here, but for context, it's an import of devices that have IP addresses, and the onAfter transform script takes the "plain" IP address from the source data, creates a new IP Address CI from it, adds the cmdb relationship between the ip address and the target record, and then updates the IP Address field of the target record (the device that was just processed by the transform map).

 

I have built a dumbed-down version of it on my dev instance, where I import Incidents, and update the Impact field in an onAfter transform script. The transform map has just one field mapping, Short Description.

 

There's an onAfter transform script that updates a field on the target record, and then calls target.update():

 

(function runTransformScript(source, map, log, target /*undefined onStart*/ ) {
	target.impact = 2;
	target.update();
})(source, map, log, target);

 

 

Then, there's an "after update/insert" BR on the incident table, which just contains a log statement, but the important thing is that the BR has a condition: It should only trigger if the Short Description field of the Incident changes.

MaxNowak_0-1713172761704.png

 

So, based on this, you'd think that the BR will only trigger on the initial insert, right? The Short Description is set during the import, so it changes from null to whatever the short description in the source data is. The onAfter transform script, which updates the Impact field, should not trigger the BR, since the condition of short_description.changes() should not evaluate to true.

 

But in reality, this BR is actually triggered twice, and you can see in the log statements that it thinks that current.short_description.changes() is true in the update that is triggered by the onAfter transform script, even though that script just updated the Impact field, not the Short Description field. You can also clearly see that previous.short_description is exactly the same as current.short_description:

 

MaxNowak_1-1713173453862.png

 

It's also not like the condition of the BR doesn't work or I've made a typo or something like that, everything works as expected if I update the record manually. The BR triggers if the short description is changed, and ignores any updates otherwise.

Hi @Max Nowak,

 

Interesting, I have done some testing on my PDI as well with the configurations very similar to yours:

  • Data source with 2 columns (number and short description) with the target to the Incident table
  • Field Map (number and short description where number's coalesce is set to true)
  • onAfter Transform Map with the same script as yours
  • A BR on the Incident table (insert & update) with the same condition and script as yours

So..... if you have a coalesce field map, the BR is executed only once.

But if you don't have a coalesce (i.e. I removed the number field map from the Transform Map), the BR is executed twice.

The top 2 logs of the screenshot below represent the transformation where there is no coalesce and the last log represents where a coalesce was set.

JamesChun_0-1713216415047.png

 

What's interesting is, even if you don't update any fields within onAfter Transform Script and just have target.update(), the BR is executed twice.

 

Not entirely sure what's going on, but is it possible for you to set up a coalesce field map?

That (hopefully) should fix the issue.

 

Cheers