- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-23-2025 12:57 PM
I have a requirement where I need to create a RITM on insert of a Case.
I have a Business Rule which in turn is calling a script include
and script include has below code:
BR is calling the function and infact first part of the code is also working fine where I am gliding a table to get the sys_id of catalog item.
It's the new sn_sc.CartJS API which seems to be creating issue.
I am getting the log till - gs.info("Testing, item created);
I am not getting last log.
If somebody has previously done this or knows how to do it, please assist.
Solved! Go to Solution.
- Labels:
-
Request Management
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-24-2025 01:25 AM
ServiceNow – Create RITM on Case Insert using sn_sc.CartJS (Working Pattern)
Your symptoms
- You see the log “Testing, item created” but not “Testing, RITM created”.
- The CartJS step is likely erroring out (and your gs.info lines also have syntax issues).
Top 8 pitfalls that usually break CartJS from a Business Rule / Script Include
1) Syntax errors in logs
- You have missing closing quotes: gs.info("Testing, item created); and gs.info("Testing, RITM created);
2) Wrong execution context
- CartJS executes as the current session user. If your BR is async/system, it may lack catalog access or requester context. Prefer AFTER INSERT, synchronous.
3) Missing catalog item or wrong sys_id type
- Ensure catItem is a string (sys_id), not a GlideElement. Use catItem = String(catSrch.getValue('u_catalog_item'));
4) Variables must use the **internal variable names**
- E.g., 'customer_name' must match the variable Name on the catalog item (not the label).
5) Required variables not provided
- If the item has mandatory variables, CartJS will fail. Provide all required ones or default them.
6) Requested for / cart user context
- If needed, set 'sysparm_requested_for' and/or impersonate the case contact user when creating the cart.
7) Use try/catch and check return objects
- CartJS returns objects with IDs; log them and handle failures.
😎 Scope / API availability
- Ensure plugin com.glideapp.servicecatalog and API sn_sc.CartJS are accessible in your scope. If not, use GlideRecord insert on sc_cart_item + sc_req_item via sn_sc.CartJS only.
Recommended, robust pattern
- Business Rule (Table: sn_customerservice_case) – When: after insert – Condition: your criteria – Calls Script Include function.
- Script Include (server-side, not client-callable).
Sample Script Include function (drop-in)
---------------------------------------
createRitmFromCase: function(caseGr) {
// 0) Guard: find catalog item
var catId = '';
var catSrch = new GlideRecord('sn_customerservice_case_itsm_decision');
catSrch.addQuery('u_category', caseGr.getValue('category'));
catSrch.query();
if (catSrch.next()) {
catId = String(catSrch.getValue('u_catalog_item'));
}
if (!catId) {
gs.error('RITM create: No catalog item found for category=' + caseGr.getDisplayValue('category'));
return null;
}
try {
gs.info('RITM create: building cart for case ' + caseGr.getValue('number') + ', catItem=' + catId);
// 1) Prepare item payload
var vars = {
// Use variable INTERNAL NAMES here:
'customer_name': caseGr.getDisplayValue('contact') || caseGr.getValue('contact'),
// add other required vars...
};
var item = {
'sysparm_id': catId,
'sysparm_quantity': '1',
'variables': vars,
// optionally set who it's for:
'sysparm_requested_for': caseGr.getValue('opened_for') || gs.getUserID()
};
// 2) Create cart and add item
var cart = new sn_sc.CartJS();
var addRes = cart.addToCart(item);
// addRes may include 'sys_id' of sc_cart_item and 'cart_id'
gs.info('RITM create: addToCart result = ' + new global.JSON().encode(addRes));
// 3) Checkout / place order
var orderRes = cart.checkoutCart(); // places the order for current user context
gs.info('RITM create: checkout result = ' + new global.JSON().encode(orderRes));
// orderRes typically includes: number, request_id (REQ), ritm_ids (array)
if (orderRes && orderRes.ritm_ids && orderRes.ritm_ids.length > 0) {
gs.info('RITM create: created RITMs = ' + orderRes.ritm_ids.join(','));
// Optionally relate Case↔RITM:
try {
var ritmGR = new GlideRecord('sc_req_item');
if (ritmGR.get(orderRes.ritm_ids[0])) {
// e.g., make a related record
caseGr.u_ritm = ritmGR.getUniqueValue(); // if you have a field to store the link
caseGr.update();
}
} catch (e2) {
gs.warn('RITM create: could not link case to RITM: ' + e2.message);
}
return orderRes;
} else {
gs.error('RITM create: checkout returned no RITM IDs');
return null;
}
} catch (e) {
gs.error('RITM create: exception: ' + e.message);
return null;
}
}
Key notes
- Fix your logging lines (close quotes).
- Ensure the BR runs AFTER INSERT and not async for the first pass. If you must run async, confirm the user context has catalog access.
- If you need the RITM to be created as the Case’s contact or opened_for, consider impersonating for the operation:
```js
var sess = gs.getSession();
var original = gs.getUserID();
if (caseGr.opened_for) sess.impersonate(caseGr.opened_for);
// run CartJS here
sess.impersonate(original); // restore
```
- If checkoutCart() is blocked by required variables, supply them all or set defaults at the item level.
Minimal fix to your original snippet
------------------------------------
- Close the quotes on gs.info lines.
- Convert u_catalog_item to string sys_id and verify variable names.
Example:
var catItem = String(catSrch.getValue('u_catalog_item'));
var cart = new sn_sc.CartJS();
var item = {
'sysparm_id': catItem,
'sysparm_quantity': '1',
'variables': {
'customer_name': caseGr.getDisplayValue('contact')
}
};
gs.info('Testing, item created');
var cartVals = cart.addToCart(item);
var checkoutVals = cart.checkoutCart();
gs.info('Testing, RITM created');
Troubleshooting checklist
- Confirm catItem sys_id exists and is Active.
- Confirm the current execution user has permission to order that item.
- Check if the item requires additional variables (UI Policy/mandatory).
- Use System Logs → All to capture CartJS errors (they are server-side).
- Temporarily wrap with try/catch and gs.error(e.message) for visibility.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-23-2025 02:58 PM
Hi @jainankit07,
your script doesn't contain the creation part..
a simple draft example could be:
var demoGR = new GlideRecord('target_table'); //sc_req_item
demoGR.initialize(); //to start the insertion
demoGR.field_nameOne = "Assign your value here";
demoGR.field_nameTwo = "Assign your value here";
demoGR.insert(); //end the insertion
Let me know what do you think about this
This reply is 100 % GlideFather and 0 % AI
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-24-2025 12:10 AM
do you have 2 step checkout in your instance?
possibly it's failing because of that
Did you print what's the error in logs?
💡 If my response helped, please mark it as correct ✅ and close the thread 🔒— this helps future readers find the solution faster! 🙏
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-24-2025 01:41 AM
so what was the solution and what was the issue?
please share so that it helps future members
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-25-2025 10:27 AM
Hi @Ankur Bawiskar ,
I passed sys_id after converting to string, then it worked.
But I am facing a new challenge now.
The requirement was to create a case via record producer, and this case in turn will create RITM, but now, because of this n_sc.Cart() this record producer is creating 70-100 records. What should I do now?
Below is the latest code, which I thought is working fine
There is some REST call I saw in transactions which is doing a lot of SQL queries and taking time.
The moment I disabled this code, it again began to create single Case record from producer
