Suite Script Developer Guide
Suite Script Developer Guide
Guide
2025.1
This software and related documentation are provided under a license agreement containing restrictions
on use and disclosure and are protected by intellectual property laws. Except as expressly permitted
in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast,
modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any
means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for
interoperability, is prohibited.
The information contained herein is subject to change without notice and is not warranted to be error-
free. If you find any errors, please report them to us in writing.
If this is software, software documentation, data (as defined in the Federal Acquisition Regulation), or
related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the
U.S. Government, then the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated software,
any programs embedded, installed, or activated on delivered hardware, and modifications of such
programs) and Oracle computer documentation or other Oracle data delivered to or accessed by
U.S. Government end users are "commercial computer software," "commercial computer software
documentation," or "limited rights data" pursuant to the applicable Federal Acquisition Regulation and
agency-specific supplemental regulations. As such, the use, reproduction, duplication, release, display,
disclosure, modification, preparation of derivative works, and/or adaptation of i) Oracle programs
(including any operating system, integrated software, any programs embedded, installed, or activated
on delivered hardware, and modifications of such programs), ii) Oracle computer documentation and/
or iii) other Oracle data, is subject to the rights and limitations specified in the license contained in the
applicable contract. The terms governing the U.S. Government's use of Oracle cloud services are defined
by the applicable contract for such services. No other rights are granted to the U.S. Government.
This software or hardware is developed for general use in a variety of information management
applications. It is not developed or intended for use in any inherently dangerous applications, including
applications that may create a risk of personal injury. If you use this software or hardware in dangerous
applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other
measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages
caused by use of this software or hardware in dangerous applications.
Oracle®, Java, and MySQL are registered trademarks of Oracle and/or its affiliates. Other names may be
trademarks of their respective owners.
Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks
are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD,
Epyc, and the AMD logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a
registered trademark of The Open Group.
This software or hardware and documentation may provide access to or information about content,
products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and
expressly disclaim all warranties of any kind with respect to third-party content, products, and services
unless otherwise set forth in an applicable agreement between you and Oracle. Oracle Corporation and
its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use
of third-party content, products, or services, except as set forth in an applicable agreement between you
and Oracle.
This documentation is in pre-General Availability status and is intended for demonstration and preliminary
use only. It may not be specific to the hardware on which you are using the software. Oracle Corporation
and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to
this documentation and will not be responsible for any loss, costs, or damages incurred due to the use of
this documentation.
If this document is in private pre-General Availability status:
The information contained in this document is for informational sharing purposes only and should be
considered in your capacity as a customer advisory board member or pursuant to your pre-General
Availability trial agreement only. It is not a commitment to deliver any material, code, or functionality, and
should not be relied upon in making purchasing decisions. The development, release, timing, and pricing
of any features or functionality described in this document may change and remains at the sole discretion
of Oracle.
This document in any form, software or printed matter, contains proprietary information that is the
exclusive property of Oracle. Your access to and use of this confidential material is subject to the terms
and conditions of your Oracle Master Agreement, Oracle License and Services Agreement, Oracle
PartnerNetwork Agreement, Oracle distribution agreement, or other license agreement which has
been executed by you and Oracle and with which you agree to comply. This document and information
contained herein may not be disclosed, copied, reproduced, or distributed to anyone outside Oracle
without prior written consent of Oracle. This document is not part of your license agreement nor can it be
incorporated into any contractual agreement with Oracle or its subsidiaries or affiliates.
Documentation Accessibility
For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program website
at https://www.oracle.com/corporate/accessibility.
Oracle customers that have purchased support have access to electronic support through My Oracle
Support. For information, visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info or visit http://
www.oracle.com/pls/topic/lookup?ctx=acc&id=trs if you are hearing impaired.
Sample Code
Oracle may provide sample code in SuiteAnswers, the Help Center, User Guides, or elsewhere through
help links. All such sample code is provided "as is” and “as available”, for use only with an authorized
NetSuite Service account, and is made available as a SuiteCloud Technology subject to the SuiteCloud
Terms of Service at www.netsuite.com/tos.
Oracle may modify or remove sample code at any time without notice.
As the Service is a multi-tenant service offering on shared databases, Customer may not use the Service
in excess of limits or thresholds that Oracle considers commercially reasonable for the Service. If Oracle
reasonably concludes that a Customer’s use is excessive and/or will cause immediate or ongoing
performance issues for one or more of Oracle’s other customers, Oracle may slow down or throttle
Customer’s excess use until such time that Customer’s use stays within reasonable limits. If Customer’s
particular usage pattern requires a higher limit or threshold, then the Customer should procure a
subscription to the Service that accommodates a higher limit and/or threshold that more effectively aligns
with the Customer’s actual usage pattern.
Beta Features
This software and related documentation are provided under a license agreement containing restrictions
on use and disclosure and are protected by intellectual property laws. Except as expressly permitted
in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast,
modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any
means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for
interoperability, is prohibited.
The information contained herein is subject to change without notice and is not warranted to be error-
free. If you find any errors, please report them to us in writing.
If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it
on behalf of the U.S. Government, then the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated software,
any programs embedded, installed or activated on delivered hardware, and modifications of such
programs) and Oracle computer documentation or other Oracle data delivered to or accessed by
U.S. Government end users are "commercial computer software" or “commercial computer software
documentation” pursuant to the applicable Federal Acquisition Regulation and agency-specific
supplemental regulations. As such, the use, reproduction, duplication, release, display, disclosure,
modification, preparation of derivative works, and/or adaptation of i) Oracle programs (including any
operating system, integrated software, any programs embedded, installed or activated on delivered
hardware, and modifications of such programs), ii) Oracle computer documentation and/or iii) other
Oracle data, is subject to the rights and limitations specified in the license contained in the applicable
contract. The terms governing the U.S. Government’s use of Oracle cloud services are defined by the
applicable contract for such services. No other rights are granted to the U.S. Government.
This software or hardware is developed for general use in a variety of information management
applications. It is not developed or intended for use in any inherently dangerous applications, including
applications that may create a risk of personal injury. If you use this software or hardware in dangerous
applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other
measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages
caused by use of this software or hardware in dangerous applications.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks
of their respective owners.
Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks
are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD,
Epyc, and the AMD logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a
registered trademark of The Open Group.
This software or hardware and documentation may provide access to or information about content,
products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and
expressly disclaim all warranties of any kind with respect to third-party content, products, and services
unless otherwise set forth in an applicable agreement between you and Oracle. Oracle Corporation and
its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use
of third-party content, products, or services, except as set forth in an applicable agreement between you
and Oracle.
This documentation is in pre-General Availability status and is intended for demonstration and preliminary
use only. It may not be specific to the hardware on which you are using the software. Oracle Corporation
and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to
this documentation and will not be responsible for any loss, costs, or damages incurred due to the use of
this documentation.
The information contained in this document is for informational sharing purposes only and should be
considered in your capacity as a customer advisory board member or pursuant to your pre-General
Availability trial agreement only. It is not a commitment to deliver any material, code, or functionality, and
should not be relied upon in making purchasing decisions. The development, release, and timing of any
features or functionality described in this document remains at the sole discretion of Oracle.
This document in any form, software or printed matter, contains proprietary information that is the
exclusive property of Oracle. Your access to and use of this confidential material is subject to the terms
and conditions of your Oracle Master Agreement, Oracle License and Services Agreement, Oracle
PartnerNetwork Agreement, Oracle distribution agreement, or other license agreement which has
been executed by you and Oracle and with which you agree to comply. This document and information
contained herein may not be disclosed, copied, reproduced, or distributed to anyone outside Oracle
without prior written consent of Oracle. This document is not part of your license agreement nor can it be
incorporated into any contractual agreement with Oracle or its subsidiaries or affiliates.
Table of Contents
Setting Up Your SuiteScript Environment .................................................................................... 1
Showing Record and Field IDs in Your Account ........................................................................ 2
Setting Roles and Permissions for SuiteScript .......................................................................... 6
Setting Up Your SuiteScript Development Environment ............................................................. 7
SuiteScript Governance and Limits ............................................................................................. 9
Script Type Usage Unit Limits ............................................................................................... 9
SuiteScript 2.x API Governance ............................................................................................ 11
Monitoring Script Usage ..................................................................................................... 33
Governance on Script Logging ............................................................................................ 34
Search Result Limits ........................................................................................................... 35
Script Execution Time Limits ................................................................................................ 36
SuiteScript Best Practices ........................................................................................................ 38
General Development Best Practices .................................................................................... 38
Client Script Best Practices .................................................................................................. 42
Map/Reduce Script Best Practices ........................................................................................ 44
Scheduled Script Best Practices ........................................................................................... 46
Suitelets and UI Object Best Practices ................................................................................... 47
User Event Script Best Practices ........................................................................................... 48
Optimizing SuiteScript Performance ..................................................................................... 49
SuiteScript Security Considerations ........................................................................................... 51
SuiteScript Debugger ............................................................................................................. 53
SuiteScript Debugger Overview ............................................................................................ 53
Debugging Overview .......................................................................................................... 55
Debugging SuiteScript 1.0 and SuiteScript 2.0 Scripts .............................................................. 57
Script Debugger Interface ............................................................................................... 57
On-Demand Debugging of SuiteScript 1.0 and SuiteScript 2.0 Scripts ..................................... 66
Debugging Deployed SuiteScript 1.0 and SuiteScript 2.0 Server Scripts ................................... 68
Tips for Debugging SuiteScript 1.0 and SuiteScript 2.0 Scripts ............................................... 72
Debugging SuiteScript 2.1 Scripts ........................................................................................ 72
2.1 Script Debugger Overview ......................................................................................... 73
Introduction to Chrome DevTools for SuiteScript 2.1 Script Debugging ................................... 74
On-Demand Debugging of SuiteScript 2.1 Scripts ............................................................... 80
Debugging Deployed SuiteScript 2.1 Server Scripts ............................................................. 81
Tips for Debugging SuiteScript 2.1 Scripts ......................................................................... 88
Debugging Client Scripts .................................................................................................... 88
Debugging a RESTlet ......................................................................................................... 90
Script Debugger Metering and Permissions ........................................................................... 91
SuiteCloud Processors ............................................................................................................ 93
SuiteCloud Processors Terminology ...................................................................................... 93
SuiteCloud Processors Basic Architecture .............................................................................. 94
SuiteCloud Processors Supported Task Types ......................................................................... 96
SuiteCloud Processors Processor Allotment Per Account .......................................................... 97
SuiteCloud Processors Priority Levels .................................................................................... 98
SuiteCloud Processors Priority Settings Page ..................................................................... 99
SuiteCloud Processors Priority Scheduling Examples .......................................................... 100
SuiteCloud Processors Priority Elevation and Processor Reservation (Advanced Settings) .............. 109
SuiteScript Monitoring, Auditing, and Logging .......................................................................... 112
Using the Script Execution Log Tab .................................................................................... 112
Viewing a List of Script Execution Logs ................................................................................ 114
The Scripted Records Page ................................................................................................ 114
SuiteScript Monitoring with the Application Performance Management (APM) ............................ 121
Setting Runtime Options ................................................................................................... 121
Setting Script Execution Event Type from the UI ............................................................... 122
Setting Script Execution Log Levels ................................................................................. 123
Executing Scripts Using a Specific Role ............................................................................ 124
Setting Available Without Login ...................................................................................... 125
Setting Script Deployment Status ................................................................................... 127
Defining Script Audience ............................................................................................... 128
Using the Context Filtering Tab ...................................................................................... 130
Reviewing Outbound HTTPS and SFTP Requests ................................................................... 136
Working with the SuiteScript Records Browser ......................................................................... 137
Finding a Record or Subrecord .......................................................................................... 138
Understanding the Record Summary .................................................................................. 139
Deleted Record Search ..................................................................................................... 141
Creating Script Parameters (Custom Fields) .............................................................................. 142
Creating Script Parameters Overview .................................................................................. 142
Creating Script Parameters ................................................................................................ 143
Referencing Script Parameters ........................................................................................... 145
Setting Script Parameter Preferences .................................................................................. 146
SuiteScript IDs ..................................................................................................................... 149
Permission Names and IDs ............................................................................................... 149
Feature Names and IDs .................................................................................................... 187
Preference Names and IDs ................................................................................................ 197
Task IDs ......................................................................................................................... 214
Button IDs ...................................................................................................................... 214
Working with UI Objects ....................................................................................................... 218
Understanding NetSuite Assistants ..................................................................................... 218
Single Page Applications ....................................................................................................... 220
Introduction to Single Page Applications ............................................................................. 220
Components and Structure of Single Page Applications ..................................................... 222
Understanding the Single Page Application Execution Process ............................................ 226
NetSuite User Interface Framework for Single Page Applications ......................................... 226
Single Page Application Samples .................................................................................... 226
Single Page Application Creation And Development ............................................................... 227
Prerequisites for Single Page Applications ....................................................................... 228
Creating a Single Page Application ................................................................................. 228
Developing Single Page Applications ............................................................................... 233
Troubleshooting Single Page Applications ........................................................................ 237
Single Page Application Management ................................................................................. 244
Managing a Single Page Application from SuiteCloud Development Framework ...................... 244
Managing a Single Page Application from the NetSuite User Interface .................................. 245
SuiteScript FAQ ................................................................................................................... 248
Setting Up Your SuiteScript Environment 1
Before working with SuiteScript, you must configure both your NetSuite account and SuiteScript
development environment. To do so, see the following:
■ Enabling SuiteScript
■ Showing Record and Field IDs in Your Account
■ Setting Roles and Permissions for SuiteScript
■ Setting Up Your SuiteScript Development Environment
Enabling SuiteScript
Before you can use SuiteScript, a user with the Administrator role must enable the SuiteScript features
that you plan to use.
To enable SuiteScript:
1. Go to Setup > Company > Enable Features.
2. Click the SuiteCloud subtab.
3. Under SuiteScript, check the Client SuiteScript or Server SuiteScript box (or both, depending on
the scripts you want to run).
4. Click Save.
Note: If the Client SuiteScript feature is enabled, the Custom Code subtab becomes available
on entry and transaction forms (see the following screenshot). On this subtab, you select the client
script that you want to associate with the current form. For information about attaching client
scripts to NetSuite forms, see the help topic Associating Custom Code (Client SuiteScript) Files With
Custom Forms.
■ Set up roles and permissions for SuiteScript – Roles and permissions determine a user's level of
access to specific areas in NetSuite. For information about SuiteScript permissions, see Setting Roles
and Permissions for SuiteScript.
■ Set the preference to show internal IDs – Internal record and field IDs are used as parameters in
SuiteScript code. For information about the preference and how to view internal IDs, see Showing
Record and Field IDs in Your Account,
■ Set up your development environment – NetSuite provides a SuiteCloud plug-in or extension
for specific IDEs. You can also use other development tools to create SuiteScript files. For more
information, see Setting Up Your SuiteScript Development Environment
After completing the SuiteScript environment setup, see the tutorial in SuiteScript 2.x Hello World for a
sample SuiteScript implementation.
Records and fields are referenced in SuiteScript through their internal IDs. Internal IDs are unique
identifiers that are associated to a record or field, and remain constant even if the record or field value is
changed.
To configure your NetSuite account to display record and field IDs, see Show Internal IDs Preference.
If the Show Internal IDs preference is already checked, read the following sections for information about
viewing internal IDs from within NetSuite:
For examples of how internal IDs are referenced in the SuiteScript API, see the help topic
record.load(options) or search.load(options).
Important: When writing SuiteScript, all internal IDs must be specified in lowercase.
For example, to see the internal IDs of customer records, go to Lists > Relationships > Customers
(Administrator). The internal ID of each record in the customer record list is found under the Internal ID
column (see the following screenshot).
When the Show Internal IDs preference is cleared, or if the internal IDs aren't shown on a particular
page within NetSuite, you can see the record's internal ID by hovering over a link to that record. The
internal ID is shown as a parameter in the URL in the browser status bar.
The following screenshot shows that if you hover over a link to the ABC Co. customer record, the internal
record ID (1766) appears in the browser status bar.
Tip: You can also get the internal ID of a record type (for example, ‘salesorder’) by going to the
SuiteScript Records Browser. For information about using the SuiteScript Records Browser, see
Working with the SuiteScript Records Browser in the NetSuite Help Center.
■ Internal IDs for Standard and Custom Fields in Field Level Help Window
■ Internal IDs for Custom Fields on List Pages
■ Working with the SuiteScript Records Browser
Not all fields are visible to NetSuite users., You can use the SuiteScript Records Browser to find the
internal ID of any field.
Internal IDs for Standard and Custom Fields in Field Level Help
Window
When the Show Internal IDs preference box is checked, you can view internal field IDs for both standard
and custom fields by clicking the field label in the UI. The following screenshot shows the Field Level Help
window that opens when you click a field label. In the example, the Company field label is clicked. The
internal ID for the Company field is companyname, which appears in the bottom-right corner of the Field
Level Help window.
Note: When creating custom fields, you can specify your own field ID or use the default ID
assigned by NetSuite. To ensure that the field IDs make sense in the context of your business
environment, you should define your own custom field IDs. For detailed information about
creating custom fields and assigning custom field IDs, refer to Custom Fields.
NetSuite provides standard roles with predefined permissions. A role (and its set of predefined
permissions) lets customers, vendors, partners, and employees access specific areas of your data. Each
role grants certain access levels for each permission. Use the Administrator role for complete access to all
SuiteScript functionality, or use the permissions in the table to allow more granular access.
For more information about roles and permissions, see the help topic NetSuite Users & Roles.
Note: If you customize a role to add SuiteScript permissions, you must also include the
permissions to customize entry and transaction forms.
SuiteScript permissions
View script records and script deployment records. Role with SuiteScript
permission (View level)
Create and view script records and script deployment records. Role with SuiteScript
permission (Create level)
Create, view, and edit script records and script deployment records. Role with SuiteScript
permission (Edit level)
Use Save and Execute from the script deployment record UI to execute an Role with SuiteScript
on-demand scheduled script or an on-demand map/reduce script. permission (Full level)
Debug a SuiteScript 1.0, SuiteScript 2.0, or SuiteScript 2.x script. Role with SuiteScript
permission (Full level)
Use an API (for example, ScheduledScriptTask.submit()) to execute an on-demand Role with SuiteScript
scheduled script or an on-demand map/reduce script. Scheduling permission (Full
level)
Execute a script with one of the following APIs: Role with SuiteScript
Scheduling permission (Full
■ SuiteScript 1.0 (see the help topic SuiteScript 1.0 Documentation) level)
□ nlobjContext.getPercentageComplete()
□ nlobjContext.setPercentageComplete(pct)
■ SuiteScript 2.x: Script.percentComplete
After configuring your NetSuite account for SuiteScript, you also need to set up your SuiteScript
development environment. The following topics describe how to set up your development environment:
If you use a development tool or IDE other than the SuiteCloud IDEs, see the following:
Note: For scripts to run in the Customer, Vendor, Partner, or Employee Center, select the
associated role on the Audience subtab of the script deployment record. Additionally, script files
and any files referenced by the script must have either the Company-Wide Usage or Available
Without Login preference enabled on the file record in the File Cabinet. For more information, see
the help topic Permissions and File Cabinet Files.
3. On the popup window that appears, select the file you want to upload and click Open.
Note: If you make changes to a SuiteScript file that already exists in the File Cabinet, follow steps
1–3 to re-upload the changed file. Click OK to overwrite the previous file and load your changes.
NetSuite uses a SuiteScript governance model to optimize performance, based on usage units. If the
number of allowable usage units is exceeded, script execution is terminated.
Usage units are tracked in two ways: by script type and by API. Each script type and each SuiteScript API
has a set number of usage units.
In map/reduce scripts, keys are limited to 3,000 characters (specifically, in mapContext or reduceContext
objects). You'll also see error messages if a key is longer than 3,000 characters or a value is larger than
10 MB. Keys longer than 3,000 characters will return the error KEY_LENGTH_IS_OVER_3000_BYTES. Values
larger than 10 MB will return the error VALUE_LENGTH_IS_OVER_10_MB.
When using mapContext.write() or reduceContext.write(), keep your key strings under 3,000 characters
and value strings under 10 MB. Also, consider the potential length of any dynamically generated strings,
which might exceed these limits. It's also a good idea to avoid using keys to pass data -use values instead.
You can find governance limits for each SuiteScript 2.x API in their respective method topics. Methods
are organized by modules, and all modules are listed in the help topic SuiteScript 2.x Modules. Also see
SuiteScript 2.x API Governance.
Important: SuiteScript thresholds are based on the volume of activity that a company's users
can manually generate. However, automated functions that generate excessive levels of activity
may trigger metering of script execution as referenced in the NetSuite Main Terms of Service
(TOS).
Governance limits are also enforced on certain aspects of script execution. When you run a search using
the N/search module, the number of search results you receive is limited. There are also limits on how
long a script can run, based on the script type. See the following help topics to learn about these limits:
Important: NetSuite uses internal mechanisms to detect scripts that may include
infinite loops when executing. When they occur, script execution is terminated and an
SSS_INSTRUCTION_COUNT_EXCEEDED error message is thrown. If you receive this error, you should
examine all of the execution loops in your script to ensure that they contain either a terminating
condition or a condition that can be met.
The following table lists the maximum allowable usage units for each SuiteScript (1.0 and 2.x) script type.
You can use the Script.getRemainingUsage() method to see how many usage units you have remaining
for a particular script.
Bundle Installation 10,000 The limit is 10,000 usage units per execution.
Scripts (SuiteScript
1.0)
SuiteScript 2.x
Bundle Installation
Script Type
For information about record-and form-level client scripts, see the help topic
Record-Level and Form-Level Script Deployments.
SuiteScript 2.x Map/ — Map/reduce scripts are available only in SuiteScript 2.x.
Reduce Script Type
There are no limits imposed on the full duration of a map/reduce script
deployment instance. Instead, isolated components of the deployment, such
as the usage units used by a single method invocation, are regulated. For
more information, see the help topic Map/Reduce Governance.
Mass Update 1,000 The limit is 1,000 usage units per record or execution of the script.
Scripts (SuiteScript
1.0)
SuiteScript 2.x
Portlet Script Type
RESTlets (SuiteScript 5,000 The SuiteScript governance model for RESTlets tracks usage units on the API
1.0) level and the script level. For more information, see the help topic RESTlet
Governance and Security
SuiteScript 2.x
RESTlet Script Type
Scheduled Scripts 10,000 Within one scheduled script, all actions combined cannot exceed
(SuiteScript 1.0) 10,000 usage units. For example, a scheduled script that includes two
calls to record.transform(options) and one call to email.send(options)
SuiteScript 2.x consumes from 24 to 40 usage units (depending on the record type for
Scheduled Script record.transform(options)) out of a possible 10,000 usage units available.
Type
If you have a scheduled script with potentially long execution times, you
should consider using a map/reduce script instead. SuiteScript 2.x does not
have a method to allow you to set recovery points or provide a yield to avoid
exceeding the allowed governance for a scheduled script. A map/reduce
script has built-in yielding and can be submitted for processing in the same
ways as a scheduled script.
SuiteScript 2.x SDF 10,000 The limit is 10,000 usage units per execution.
Installation Script
Type
Suitelets 1,000 Within one Suitelet, all actions combined cannot exceed 1,000 usage units.
(SuiteScript 1.0) For example, a Suitelet that calls record.create(options) and http.get(options)
consumes from 12 to 20 usage units (depending on the record type for
SuiteScript 2.x record.create(options)) out of a possible 1,000 usage units available.
Suitelet Script Type
Regardless of the 1,000 unit limit for Suitelets, you should create your
Suitelets to be responsive to users, otherwise user experience may be
impacted.
User Event Scripts 1,000 Regardless of the 1,000 usage unit limit for user event scripts, you should
(SuiteScript 1.0) create your scripts so that they are responsive to users, otherwise user
experience may be impacted.
SuiteScript 2.x User
Event Script Type
Workflow Action 1,000 Within one workflow state, all actions combined cannot exceed 1,000
Scripts (SuiteScript usage units. For example, if you have developed a custom action (using a
1.0) workflow action script) that consumes 990 usage units, be aware of the unit
consumption of the other actions within that state.
SuiteScript 2.x
Workflow Action
Script Type
(also referred to as
Custom Action in
SuiteFlow)
Core Plug-ins Varies based on The default limit for core plug-ins that do not have more restrictive limits
the plug-in defined is 10,000. See the help topic for each core plug-in for any specific
usage unit limits.
Custom Plug-ins 10,000 The limit is 10,000 usage units per plug-in.
SSP Application 1,000 For more information, see the help topic SSP Application Governance.
Scripts
Note: There is also a limit of 1,000 usage units when using the SuiteScript Debugger. For more
information, see Script Debugger Metering and Permissions.
The following table shows the governance usage units used for each SuiteScript 2.x method. You can use
the Script.getRemainingUsage() method to see how many usage units you have remaining for a particular
script.
The governance model takes into account the NetSuite processing requirements for three categories
of records: custom records, standard transaction records, and standard non-transaction records. For
example, custom records require less processing than standard records, therefore, the usage unit
cost for custom records is lower than for standard records. Similarly, standard non-transaction records
require less processing than standard transaction records, therefore, the usage unit cost for standard
non-transaction records is lower than for standard transaction records. Standard transaction records
include records such as cash refund, customer deposit, and item fulfillment. Standard non-transaction
records include records such as activity, inventory item, and customer. You can see an example of this in
the N/record module methods listed below.
Record categories are included in the SuiteScript Supported Records help topic. Record types categorized
as activity, communication, customization, entity, file cabinet, item, list, marketing, subrecord, support, or
website are considered to be standard non-transaction records.
For tips on how to monitor how many usage units your script is using, see Monitoring Script Usage.
Action.promise(options)
Action.execute(options) None
Action.execute.promise(options)
Action.executeBulk(options) 50
action.getBulkStatus(options) None
action.execute(options) None
action.execute.promise(options)
action.executeBulk(options) 50
action.find(options) None
action.find.promise(options)
action.get(options) None
action.get.promise(options)
auth.changePassword(options) 10
Cache.put(options) 1
Cache.remove(options) 1
cache.getCache(options) None
certificateControl.createCertificate(options) 10
certificateControl.deleteCertificate(options) 10
certificateControl.findCertificates(options) 10
certificateControl.findUsages(options) 10
certificateControl.loadCertificate(options) 10
recordView.viewWebsite(options) None
Archiver.archive(options) None
compress.createArchiver() None
compress.gzip(options) None
compress.gunzip(options) None
Cipher.update(options) None
Decipher.final(options) None
Decipher.update(options) None
Hash.digest(options) None
Hash.update(options) None
Hmac.digest(options) None
Hmac.update(options) None
crypto.createCipher(options) None
crypto.createDecipher(options) None
crypto.createHash(options) None
crypto.createHmac(options) None
crypto.createSecretKey(options) None
SignedXml.asString() None
SignedXml.asXml() None
Signer.sign(options) None
Signer.update(options) None
Verifier.update(options) None
Verifier.verify(options) None
certificate.createSigner(options) 10
certificate.createVerifier(options) 10
certificate.verifyXmlSignature(options) 10
certificate.signXml(options) 10
random.generateInt(options) None
random.generateUUID() None
CurrentRecord.commitLine(options) None
CurrentRecord.findMatrixSublistLineWith None
Value(options)
CurrentRecord.findSublistLineWithValue None
(options)
CurrentRecord.getCurrentMatrixSublistValue None
(options)
CurrentRecord.getCurrentSublistIndex None
(options)
CurrentRecord.getCurrentSublistSubrecord None
(options)
CurrentRecord.getCurrentSublistText(options) None
CurrentRecord.getCurrentSublistValue None
(options)
CurrentRecord.getField(options) None
CurrentRecord.getLineCount(options) None
CurrentRecord.getMatrixHeaderCount None
(options)
CurrentRecord.getMatrixHeaderField(options) None
CurrentRecord.getMatrixHeaderValue None
(options)
CurrentRecord.getMatrixSublistField(options) None
CurrentRecord.getMatrixSublistValue(options) None
CurrentRecord.getSublist(options) None
CurrentRecord.getSublistField(options) None
CurrentRecord.getSublistText(options) None
CurrentRecord.getSublistValue(options) None
CurrentRecord.getSubrecord(options) None
CurrentRecord.getText(options) None
CurrentRecord.getValue(options) None
CurrentRecord.hasCurrentSublistSubrecord None
(options)
CurrentRecord.hasSublistSubrecord(options) None
CurrentRecord.hasSubrecord(options) None
CurrentRecord.insertLine(options) None
CurrentRecord.removeCurrentSublist None
Subrecord(options)
CurrentRecord.removeLine(options) None
CurrentRecord.removeSubrecord(options) None
CurrentRecord.selectLine(options) None
CurrentRecord.selectNewLine(options) None
CurrentRecord.setCurrentMatrixSublistValue None
(options)
CurrentRecord.setCurrentSublistText(options) None
CurrentRecord.setCurrentSublistValue None
(options)
CurrentRecord.setMatrixHeaderValue None
(options)
CurrentRecord.setMatrixSublistValue(options) None
CurrentRecord.setText(options) None
CurrentRecord.setValue(options) None
Field.getSelectOptions(options) None
Field.insertSelectOption(options) None
Field.removeSelectOption(options) None
Sublist.getColumn(options) None
currentRecord.get() None
currentRecord.get.promise()
Dataset.run() 10
Dataset.runPaged(options) 10
Dataset.save(options) 10
dataset.create(options) None
dataset.createColumn(options) None
dataset.createCondition(options) None
dataset.createJoin(options) None
dataset.createTranslation(options) None
dataset.describe(options) 10
dataset.list() 10
dataset.listPaged(options) 10
dataset.loadDataset(options) 10
email.send.promise(options)
email.sendBulk(options) 10
email.sendBulk.promise(options)
email.sendCampaignEvent(options) 10
email.sendCampaignEvent.promise(options)
File.getContents() None
File.getReader() None
File.getSegments(options) None
File.appendLine(options) None
File.lines.iterator() None
File.resetStream() None
File.save() 20
Reader.readChars(options) None
Reader.readUntil(options) None
file.create(options) None
file.delete(options) 20
file.load(options) 10
format.parse(options) None
NumberFormatter.format(options) 10
PhoneNumberFormatter.format(options) None
PhoneNumberParser.parse(options) None
format.getCurrencyFormatter(options) 10
format.getNumberFormatter(options) 10
format.spellOut(options) None
ServerRequest.getSublistValue(options) None
ServerResponse.addHeader(options) None
ServerResponse.getHeader(options) None
ServerResponse.renderPdf(options) 10
ServerResponse.sendRedirect(options) None
ServerResponse.setCdnCacheable(options) None
ServerResponse.setHeader(options) None
ServerResponse.write(options) None
ServerResponse.writeFile(options) None
ServerResponse.writeLine(options) None
ServerResponse.writePage(options) None
http.get(options) 10
http.get.promise(options)
http.delete(options) 10
http.delete.promise(options)
http.post(options) 10
http.post.promise(options)
http.put(options) 10
http.put.promise(options)
http.request(options) 10
http.request.promise(options)
SecureString.appendString(options) None
SecureString.convertEncoding(options) None
SecureString.hash(options) None
SecureString.hmac(options) None
ServerRequest.getLineCount(options) None
ServerRequest.getSublistValue(options) None
ServerResponse.addHeader(options) None
ServerResponse.getHeader(options) None
ServerResponse.renderPdf(options) 10
ServerResponse.sendRedirect(options) None
ServerResponse.setCdnCacheable(options) None
ServerResponse.setHeader(options) None
ServerResponse.write(options) None
ServerResponse.writeFile(options) None
ServerResponse.writeLine(options) None
ServerResponse.writePage(options) 10
https.createSecretKey(options) None
https.createSecureString(options) None
https.get(options) 10
https.get.promise(options)
https.delete(options) 10
https.delete.promise(options)
https.post(options) 10
https.post.promise(options)
https.put(options) 10
https.put.promise(options)
https.request(options) 10
https.request.promise(options)
https.requestRestlet(options) 10
https.requestSuiteTalkRest(options) 10
clientCertificate.get(options) 10
clientCertificate.post(options) 10
clientCertificate.put(options) 10
clientCertificate.request(options) 10
keyControl.createKey(options) 10
keyControl.deleteKey(options) 10
keyControl.findKeys(options) 10
keyControl.loadKey(options) 10
llm.createDocument(options) None
llm.embed(options) 50
llm.embed.promise(options) 50
llm.evaluatePrompt(options) 100
llm.evaluatePrompt.promise(options) 100
llm.evaluatePromptStreamed(options) 100
llm.evaluatePromptStreamed. 100
promise(options)
llm.generateText(options) 100
llm.generateText.promise(options) 100
llm.generateTextStreamed(options) 100
llm.generateTextStreamed.promise(options) 100
llm.getRemainingFreeUsage() None
llm.getRemainingFreeUsage.promise() None
llm.getRemainingFreeEmbedUsage() None
llm.getRemainingFreeEmbedUsage.promise() None
log.emergency(options)
log.error(options)
machineTranslation.translate(options) 100
machineTranslation.translate. 100
promise(options)
PiRemovalTask.run() 20
PiRemovalTask.save() 20
piremoval.createTask(options) None
piremoval.deleteTask(options) 20
piremoval.getTaskStatus(options) None
piremoval.loadTask(options) None
plugin.loadImplementation(options) None
portlet.resize() None
Component.createColumn(options) None
Component.createCondition(options) None
Component.createSort(options) None
Component.join(options) None
Component.joinFrom(options) None
Component.joinTo(options) None
PagedData.iterator() None
Query.and(conditions) None
Query.autoJoin(options) None
Query.createColumn(options) None
Query.createCondition(options) None
Query.createSort(options) None
Query.join(options) None
Query.joinFrom(options) None
Query.joinTo(options) None
Query.run() 10
Query.run.promise()
Query.runPaged(options) 10
Query.runPaged.promise(options)
Query.not(condition) None
Query.or(conditions) None
Query.toSuiteQL() None
Result.asMap() None
ResultSet.asMappedResults() None
ResultSet.iterator() None
SuiteQL.run() 10
SuiteQL.runPaged(options) 10
query.create(options) None
query.createPeriod(options) None
query.createRelativeDate(options) None
query.delete(options) 5
query.listTables(options) None
query.load(options) 5
query.load.promise(options)
query.runSuiteQL(options) 10
query.runSuiteQLPaged(options) 10
Macro(options) None
Macro.promise(options)
Macro.execute(options) None
Macro.execute.promise(options)
Record.cancelLine(options) None
Record.commitLine(options) None
Record.executeMacro(options) None
Record.executeMacro.promise(options)
Record.findMatrixSublistLineWithValue( None
options)
Record.findSublistLineWithValue(options) None
Record.getCurrentMatrixSublistValue(options) None
Record.getCurrentSublistField(options) None
Record.getCurrentSublistIndex(options) None
Record.getCurrentSublistSubrecord(options) None
Record.getCurrentSublistText(options) None
Record.getCurrentSublistValue(options) None
Record.getField(options) None
Record.getFields() None
Record.getLineCount(options) None
Record.getMacro(options) None
Record.getMacros() None
Record.getMatrixHeaderCount(options) None
Record.getMatrixHeaderField(options) None
Record.getMatrixHeaderValue(options) None
Record.getMatrixSublistField(options) None
Record.getMatrixSublistValue(options) None
Record.getSublist(options) None
Record.getSublists() None
Record.getSublistField(options) None
Record.getSublistFields(options) None
Record.getSublistSubrecord(options) None
Record.getSublistText(options) None
Record.getSublistValue(options) None
Record.getSubrecord(options) None
Record.getText(options) None
Record.getValue(options) None
Record.hasCurrentSublistSubrecord(options) None
Record.hasSublistSubrecord(options) None
Record.hasSubrecord(options) None
Record.insertLine(options) None
Record.removeCurrentSublistSubrecord( None
options)
Record.removeLine(options) None
Record.removeSublistSubrecord(options) None
Record.removeSubrecord(options) None
Record.selectLine(options) None
Record.selectNewLine(options) None
Record.setCurrentMatrixSublistValue(options) None
Record.setCurrentSublistText(options) None
Record.setCurrentSublistValue(options) None
Record.setMatrixHeaderValue(options) None
Record.setMatrixSublistValue(options) None
Record.setSublistText(options) None
Record.setSublistValue(options) None
Record.setText(options) None
Record.setValue(options) None
Sublist.getColumn(options) None
record.attach(options) 10
record.attach.promise(options)
record.detach(options) 10
record.detach.promise(options)
redirect.toRecord(options) None
redirect.toRecordTransform(options) None
redirect.toSavedSearch(options) 5
redirect.toSavedSearchResult(options) 5
redirect.toSearch(options) None
redirect.toSearchResult(options) None
redirect.toSuitelet(options) None
redirect.toTaskLink(options) None
TemplateRenderer.addQuery(options) None
TemplateRenderer.addRecord(options) None
TemplateRenderer.addSearchResults(options) None
TemplateRenderer.renderAsPdf() None
TemplateRenderer.renderPdfToResponse None
(options)
TemplateRenderer.renderAsString() None
TemplateRenderer. None
renderToResponse(options)
TemplateRenderer.setTemplateById(options) None
TemplateRenderer.setTemplateByScriptId None
(options)
render.bom(options) 10
render.create() None
render.mergeEmail(options) None
render.packingSlip(options) 10
render.pickingTicket(options) 10
render.statement(options) 10
render.transaction(options) 10
render.xmlToPdf(options) 10
Script.getRemainingUsage() None
Session.get(options) None
Session.set(options) None
User.getPermission(options) None
User.getPreference(options) None
runtime.getCurrentScript() None
runtime.getCurrentSession() None
runtime.getCurrentUser() None
runtime.isFeatureInEffect(options) None
Page.prev() 5
Page.prev.promise()
PagedData.fetch(options) 5
PagedData.fetch.promise()
Result.getValue(column) None
Result.getValue(options)
Result.getText(column) None
Result.getText(options)
ResultSet.each(callback) 10
ResultSet.each.promise(callback)
ResultSet.getRange(options) 10
ResultSet.getRange.promise(options)
Search.run() None
Search.runPaged(options) 5
Search.runPaged.promise(options)
Search.save() 5
Search.save.promise()
search.create(options) None
search.create.promise(options)
search.createColumn(options) None
search.createFilter(options) None
search.createSetting(options) None
search.delete(options) 5
search.delete.promise(options)
search.duplicates(options) 10
search.duplicates.promise(options)
search.global(options) 10
search.global.promise(options)
search.load(options) 5
search.load.promise(options)
search.lookupFields(options) 1
search.lookupFields.promise(options)
Connection.list(options) 10
Connection.makeDirectory(options) 10
Connection.move(options) 10
Connection.removeDirectory(options) 10
Connection.removeFile(options) 10
Connection.upload(options) 100
sftp.createConnection(options) None
suiteAppInfo.isSuiteAppInstalled(options) 5
suiteAppInfo.listBundlesContainingScripts 10
(options)
suiteAppInfo.listInstalledBundles() 10
suiteAppInfo.listInstalledSuiteApps() 10
suiteAppInfo.listSuiteAppsContainingScripts 10
(options)
EntityDeduplicationTask.submit() 100
MapReduceScriptTask.submit() 20
MapReduceScriptTaskStatus. 25
getCurrentTotalSize()
MapReduceScriptTaskStatus. 10
getPendingMapCount()
MapReduceScriptTaskStatus. 25
getPendingMapSize()
MapReduceScriptTaskStatus. 10
getPendingOutputCount()
MapReduceScriptTaskStatus. 25
getPendingOutputSize()
MapReduceScriptTaskStatus. 10
getPendingReduceCount()
MapReduceScriptTaskStatus. 25
getPendingReduceSize()
MapReduceScriptTaskStatus. 10
getPercentageCompleted()
MapReduceScriptTaskStatus. 10
getTotalMapCount()
MapReduceScriptTaskStatus. 10
getTotalOutputCount()
MapReduceScriptTaskStatus. 10
getTotalReduceCount()
QueryTask.addInboundDependency(options) None
QueryTask.submit() 100
RecordActionTask.submit() 50
RecordActionTask.paramCallback None
ScheduledScriptTask.submit() 20
SearchTask.addInboundDependency() None
SearchTask.submit() 100
SuiteQLTask.addInboundDependency None
(options)
SuiteQLTask.submit() 100
WorkflowTriggerTask.submit() 20
task.checkStatus(options) None
task.create(options) None
N/task/accounting/recognition MergeArrangementsTask.submit() 20
Module
MergeElementsTask.submit() 20
recognition.checkStatus(options) 50
recognition.create(options) None
transaction.void.promise(options)
translation.load(options) 1
translation.selectLocale(options) None
dialog.confirm(options) None
dialog.create(options) None
Message.show(options) None
message.create(options) None
Assistant.addFieldGroup(options) None
Assistant.addStep(options) None
Assistant.addSublist(options) None
Assistant.getField(options) None
Assistant.getFieldGroup(options) None
Assistant.getFieldGroupIds() None
Assistant.getFieldIds() None
Assistant.getFieldIdsByFieldGroup(fieldGroup) None
Assistant.getLastAction() None
Assistant.getLastStep() None
Assistant.getNextStep() None
Assistant.getStep(options) None
Assistant.getStepCount() None
Assistant.getSteps() None
Assistant.getSublist(options) None
Assistant.getSublistIds() None
Assistant.hasErrorHtml() None
Assistant.isFinished() None
Assistant.sendRedirect(options) None
Assistant.setSplash(options) None
Assistant.updateDefaultValues(values) None
AssistantStep.getFieldIds() None
AssistantStep.getLineCount(options) None
AssistantStep.getSublistFieldIds(options) None
AssistantStep.getSublistValue(options) None
AssistantStep.getSubmittedSublistIds() None
AssistantStep.getValue(options) None
Field.addSelectOption(options) None
Field.getSelectOptions(options) None
Field.setHelpText(options) None
Field.updateBreakType(options) None
Field.updateDisplaySize(options) None
Field.updateDisplayType(options) None
Field.updateLayoutType(options) None
Form.addButton(options) None
Form.addCredentialField(options) None
Form.addField(options) None
Form.addFieldGroup(options) None
Form.addPageInitMessage(options) None
Form.addPageLink(options) None
Form.addSecretKeyField(options) None
Form.addSublist(options) None
Form.addSubmitButton(options) None
Form.addSubtab(options) None
Form.addTab(options) None
Form.getButton(options) None
Form.getField(options) None
Form.getSublist(options) None
Form.getSubtab(options) None
Form.getTab(options) None
Form.getTabs() None
Form.insertField(options) None
Form.insertSublist(options) None
Form.insertSubtab(options) None
Form.insertTab(options) None
Form.removeButton(options) None
Form.updateDefaultValues(options) None
List.addButton(options) None
List.addColumn(options) None
List.addEditColumn(options) None
List.addPageLink(options) None
List.addRow(options) None
List.addRows(options) None
ListColumn.addParamToURL(options) None
ListColumn.setURL(options) None
Sublist.addButton(options) None
Sublist.addField(options) None
Sublist.addMarkAllButtons() None
Sublist.addRefreshButton() None
Sublist.getField(options) None
Sublist.getSublistValue(options) None
Sublist.setSublistValue(options) None
Sublist.updateTotallingFieldId(options) None
Sublist.updateUniqueFieldId(options) None
serverWidget.createAssistant(options) None
serverWidget.createForm(options) None
serverWidget.createList(options) None
url.resolveDomain(options) None
url.resolveRecord(options) None
url.resolveScript(options) None
url.resolveTaskLink(options) None
util.isAsyncFunction(obj) None
util.isArray(obj) None
util.isBoolean(obj) None
util.isDate(obj) None
util.isFunction(obj) None
util.isNumber(obj) None
util.isObject(obj) None
util.isRegExp(obj) None
util.isString(obj) None
workbook.create(options) None
workbook.createCalculatedMeasure(options) None
workbook.createColor(options) None
workbook.createConditionalFilter(options) None
workbook.createConditionalFormat(options) None
workbook.createConditionalFormatRule None
(options)
workbook.createConstant(options) None
workbook.createDataDimension(options) None
workbook.createDataDimensionItem(options) None
workbook.createDataMeasure(options) None
workbook.createDimensionSelector(options) None
workbook.createExpression(options) None
workbook.createFieldContext(options) None
workbook.createFontSize(options) None
workbook.createLimitingFilter(options) None
workbook.createMeasureSelector(options) None
workbook.createMeasureValueSelector None
(options)
workbook.createPathSelector(options) None
workbook.createPivotAxis(options) None
workbook.createPivot(options) None
workbook.createPositionPercent(options) None
workbook.createPositionUnits(options) None
workbook.createPositionValues(options) None
workbook.createReportStyle(options) None
workbook.createReportStyleRule(options) None
workbook.createSection(options) None
workbook.createSort(options) None
workbook.createSortByDataDimensionItem( None
options)
workbook.createSortByMeasure(options) None
workbook.createSortDefinition(options) None
workbook.createStyle(options) None
workbook.createTable(options) None
workbook.createTableColumn(options) None
workbook.createTableColumnFilter(options) None
workbook.list() 10
workbook.loadWorkbook(options) 10
workflow.trigger(options) 20
Document.createAttribute(options) None
Document.createAttributeNS(options) None
Document.createCDATASection(options) None
Document.createComment(options) None
Document.createDocumentFragment() None
Document.createElement(options) None
Document.createElementNS(options) None
Document.createProcessingInstruction None
(options)
Document.createTextNode(options) None
Document.getElementById(options) None
Document.getElementsByTagName(options) None
Document.getElementsByTagNameNS None
(options)
Document.importNode(options) None
Element.getAttribute(options) None
Element.getAttributeNode(options) None
Element.getAttributeNodeNS(options) None
Element.getAttributeNS(options) None
Element.getElementsByTagName(options) None
Element.getElementsByTagNameNS(options) None
Element.hasAttribute(options) None
Element.hasAttributeNS(options) None
Element.removeAttribute(options) None
Element.removeAttributeNode(options) None
Element.removeAttributeNS(options) None
Element.setAttribute(options) None
Element.setAttributeNode(options) None
Element.setAttributeNodeNS(options) None
Element.setAttributeNS(options) None
Node.appendChild(options) None
Node.cloneNode(options) None
Node.compareDocumentPosition(options) None
Node.hasAttributes() None
Node.hasChildNodes() None
Node.insertBefore(options) None
Node.isDefaultNamespace(options) None
Node.isEqualNode(options) None
Node.isSameNode(options) None
Node.lookupNamespaceURI(options) None
Node.lookupPrefix(options) None
Node.normalize() None
Node.removeChild(options) None
Node.replaceChild(options) None
Parser.fromString(options) None
Parser.toString(options) None
XPath.select(options) None
xml.escape(options) None
xml.validate(options) None
A user event script on a standard transaction record This script uses a total of 40 usage units:
type (such as invoice) that includes:
■ record.delete(options) uses 20 usage units for a
■ one call to record.delete(options) transaction record
A scheduled script on a standard non-transaction This script uses a total of 30 usage units:
record type (such as customer) that includes:
■ record.load(options) uses 5 usage units for a standard
■ one call to record.load(options) non-transaction record
■ one call to record.transform(options) ■ record.transform(options) uses 5 usage units for a
■ one call to email.send(options) non-standard transaction record
■ email.send(options) uses 20 usage units
You can monitor SuiteScript unit usage using the Script.getRemainingUsage() method as shown in the
following examples.
Example 1
This example shows how to instantiate the current script object and call Script.getRemainingUsage() to
write the script's remaining usage units to the execution log.
Example 2
This example shows how to instantiate the current script object and checks the remaining usage units. If
there are more than 50 usage units remaining, the script will execute a certain set of instructions.
You can also monitor script unit usage by running the script in the SuiteScript Debugger. After a script
completes execution, you can view unit usage details on the Execution Log tab in the SuiteScript
Debugger console. If usage units are exceeded, usage limit error messages are emailed to the script
owner indicating the number of usage units that were executed in the script before the usage limit error
occurred.
For more information about the SuiteScript Debugger, see the help topic SuiteScript Debugger.
NetSuite governs the amount of script execution logging that can be done. The governance model is:
■ A company can make up to 100,000 N/log calls across all scripts within a 60–minute period.
■ System error logs are purged after 60 days. User-generated logs are purged after 30 days.
Script owners are notified if a script is logging excessively and NetSuite automatically adjusts the log
level.This keeps the script running and prevents it from logging too much. For example, say one company
has 10 scripts running during a 60–minute period. If one script makes 70,000 log.debug(options) calls
within each 20–minute period, NetSuite will automatically raise the script's log level.
You can see the new log level in the Log Level field on the script's deployment page:
For example, if the offending script's log level was originally set to Debug, NetSuite will increase the
level to Audit. This means that the log.debug line of code will continue to execute, however, nothing
will be logged, because the log level for the script has been raised to Audit and the line of code is using
the Debug level. For more information about log levels, see the help topic Using Log Levels. For more
information about viewing script execution logs, see the help topic Script Execution Logs.
For more information, see the help topic N/log Module Guidelines.
Execution Log tab The capacity for script execution logs on the Execution Log tab is shared by customers on
on script and script the same NetSuite database.
deployment records
To prevent excessive logging, there's a 5 million log limit per database instance. If this limit
is reached, all logs for all customers on that database are purged. If you need to view all
logs up to 30 days on the Execution Log tab, consider creating a custom solution using
custom records to store log information from logs.
For more information, see the help topic Using the Script Execution Log Tab.
Server Script Log The capacity for script execution logs returned by the Server Script Log search is shared by
search all customers on the same NetSuite database.
To prevent excessive logging, script execution logs are governed by a total storage limit of
5 million log limit per database instance for this search. On each NetSuite server, if this limit
is reached, logs across all customers on that server are purged. If you need to search all
logs up to 30 days, consider creating a custom solution using custom records to store log
information from logs.
If a Server Script Log search is not returning logs less than 30 days old, go to Customization
> Scripting > Script Execution Logs and use the filters at the top of the Script Execution Log
page to search for logs. You can also check script deployments that have large amounts of
logging and consider lowering the Log Level to Error or Emergency or limiting the number
of log lines in your script.
Script Execution log The execution logs shown on the Script Execution log page are stored for 30 days
page regardless of volume.
For more information about the Script Execution log, see the help topic Viewing a List of
Script Execution Logs.
NetSuite sends email notifications and adds a log entry to the script's Execution Log indicating that a
script's log level has been increased. For more information about script execution log levels, see the help
topic Setting Script Execution Log Levels.
■ Search results are limited to 1,000 records when you execute SuiteScript searches using the N/search
Module. For information about working with SuiteScript searches in NetSuite, see the help topic N/
search Module.
■ If you load a saved search using search.load(options), and then call Search.run() to return a result set
of search.ResultSet objects, you may get up to 4,000 results returned. For more information, see the
help topic ResultSet.each(callback).
■ Text columns in search results have a 4000-byte limit, or about 4000 characters in English. Using
intricate character sets can lower this limit, since they need more bytes per character.
Each server script type and plug-in type has a limit on the amount of time it can run in a single execution.
If the time limit is exceeded, an SSS_TIME_LIMIT_EXCEEDED error is thrown and script execution stops.
However, a script may run for a long time, and you may not see the SSS_TIME_LIMIT_EXCEEDED error under
these conditions:
■ The script performs a large number of record operations without exceeding the usage unit limit. See
Script Type Usage Unit Limits for usage unit limits.
■ The script causes a large number of user event scripts or workflows to execute.
■ The script performs database queries or updates that collectively take a long time to finish.
Additionally, there is a 300 second (5-minute) time limit when scripts are executed in the SuiteScript 2.1
Debugger. For more information about metering in the debugger, see Script Debugger Metering and
Permissions.
The following tables list the time limit (in seconds) for each script type, core plug-in type, and custom
plug-in type.
30
300
Promotions 300
Tax Engine 60
Important: If you're using SuiteScript 1.0 or SuiteScript 2.0 for your scripts, consider converting
these scripts to SuiteScript 2.1. Use SuiteScript 2.1 to take advantage of a new runtime engine
which may improve performance, new features, and functionality enhancements, including newer
ECMAScript language features.SuiteScript 2.1 server supports ES2023 and SuiteScript 2.1 client
supports the ES version supported by the browser. For more information, see the help topics
SuiteScript Versioning Guidelines and SuiteScript 2.1.
Here are some general best practices for writing SuiteScript scripts:
Using SuiteScript ■ When you specify the modules that your script uses, make sure that the order of the
modules modules matches the order of the parameters in your main function. For example, if your
script uses the N/error, N/record, and N/file modules and you specify them in this order,
make sure that your function parameters are in the same order, as follows:
Code organization ■ Good code is well organized. Data and operations in each function or class fit together.
and structure Organize your code into reusable chunks. Many functions can be used in a variety of forms.
Any reusable functions should be stored in a common library file and then called into specific
event functions for the required forms as needed.
■ Good code is written using small, readable, reusable functions. Including too many lines of
code in one function makes it harder to understand and debug. Consider refactoring your
code to keep all functions reasonable in size.
■ Use nesting judiciously. Extensive nesting may make your script unreadable. Try to keep
your scripts as readable as possible.
■ During script development, use components, load them individually and then test each one
--inactivating all but the one you are testing when multiple components are tied to a single
user event.
Naming Good code uses meaningful naming conventions. A well written script containing descriptive
conventions names for functions, variables, IDs, provides a good structure for building comments around.
Functions:
■ Although you can use any desired naming conventions for functions within your code, you
should use custom name spaces or unique prefixes for all your function names.
■ When working with the top-level NetSuite functions in Client SuiteScript (for example the
pageInit function), you should name the new function to correspond to the NetSuite name.
For example, a pageInit function can be named pageInit or formAPageInit. If your code
is already established, you can wrap it with a top-level function that has the appropriate
naming convention.
■ Function Names: All function names should be written in lower camel case which means the
first letter of each word (except the first) is capitalized.
■ For IDs, enter all record, field, sublist, tab, and subtab IDs in lower case in your SuiteScript
code. Prefix all custom script IDs and deployment IDs with an underscore (_).
IDs:
■ For IDs, enter all record, field, sublist, tab, and subtab IDs in lower case. Prefix all custom
script IDs and deployment IDs with an underscore (_).
File names:
■ If you write SuiteScript code for multiple accounts, consider using the following file name
convention: <Company Name/Abbreviation>_<Script Type>_<Requirement Description>.js.
For example, MyCompany_CS_SetTaxable.js.
The following are suggested Script Types:
□ CS – client scripts
□ UE – user events
□ SL – Suitelet
□ RL – RESTlet
□ PL – Portlet
□ SC – Scheduled
□ MR – Map/Reduce
□ Gl – SuiteGL
□ WA – Workflow Action
□ MU – Mass Update
□ BI – Bundle Installation
Commenting ■ Thoroughly comment your code. Include comments about what the script is doing and
who authored it. This practice helps with debugging and development and assists NetSuite
Customer Support in locating problems, if necessary. It also helps anyone else who works
with the script.
■ Write useful comments. Good code comments explain what is being done and why it's being
done.
■ When documenting functions try to provide a good abstract of the actions of the function
without restating the function name.
■ A good way to write relevant comments is to plan your scripts using pseudo code and
replace the pseudo code with a relevant comment where necessary.
■ At a minimum, you should include comments: (1) for the file level disclaimer, (2) for version
control, (3) at the function level, and (4) at the logic level.
■ Note that in SuiteScript 2.x, inline comments aren't allowed within an object. You may
not see a specific error, however, your script won't function properly if you include inline
comments within an object.
White space and ■ Use white space and formatting to enhance readability rather than to minimize typing effort.
formatting The following rules should always apply:
□ All line returns within a function should be terminated with a ; (semicolon).
□ Code blocks should be tab indented.
Using IDs ■ Use static ID values in your API calls where applicable because name values can change.
Passwords ■ Don't hard-code any passwords in scripts. The password and password2 fields are
supported for scripting. For additional information, see SuiteScript Security Considerations.
Error and ■ Include proper error handling sequences in your script wherever data may be inconsistent,
exception handling not available, or invalid for certain functions. For example, if your script requires a field value
to validate another, ensure that the field value is available.
■ Use try-catch blocks. Try-catch blocks provide a way to “catch” an exception object thrown
with the try block. As soon as an exception is thrown the catch block starts. An optional
finally clause can also be used to run (guaranteed) if any exception occurs or not.
URLs ■ Don't hard-code URL links. If the domain name changes, hard-coded URLs won't work. To
prevent issues with links, use the N/url Samples.
Date and Currency ■ Use the built-in library functions whenever possible for reading/writing Date/Currency fields
fields and for querying XML documents.
Script parameters ■ Use script parameters or configuration files wherever possible, instead of hard coding
values, to ensure that scripts can be configured easily
■ You can use the runtime.getCurrentScript() function in the runtime module to reference
script parameters. For example, use the following code to obtain the value of a script
parameter named custscript_case_field:
define(['N/runtime'], function(runtime) {
function pageInit(context) {
var strField = runtime.getCurrentScript().getParameter('SCRIPT', 'custscript_case_field');
...
});
■ For security reasons, don't include confidential information in script parameters. Information
saved in script parameters can be indexed by search engines and therefore be viewable by
the public. This means, for example, that the information could be found in Google searches.
For more information, see Creating Script Parameters Overview.
Reserved words ■ Ensure that your scripts don't use any reserved words in SuiteScript. For more information,
see the help topic SuiteScript Reserved Words.
Execution contexts ■ Consider the most appropriate script execution context for your script. The script execution
context specifies how and when a script is triggered to execute. If you don’t use the
appropriate context, blocks of scripts run when they shouldn’t and result in unexpected
errors in the data and the script. For more information, see the help topic Execution
Contexts.
Loading records ■ For record Create or Edit operations, you should load records in dynamic mode. This is
required to make updates on record object.
Load records in a non-dynamic mode if you want to only get field values from the record and
update on record isn't needed.
■ Don't use record.load(options) to load a whole record when you only need to get the
value of a few fields. The performance of the load record API is similar to loading the
record in the user interface without field rendering since it loads all configuration fields
and sublists for the record. To avoid slowing down the execution of the script, use
search.lookupFields(options) to get the value of a few fields.
Invoking methods ■ You should use parameter id’s instead of parameter sequence.
■ You should use defined SuiteScript 2.0 native enums.
You may find the list of valid enums on Help and SuiteScript 2.0 API pdf.
Asynchronous ■ When using promises in your SuiteScript scripts to implement asynchronous programming,
programming you should consider the best practices listed in the Best Practices for Asynchronous
Programming with SuiteScript help topic.
Custom code ■ Place all custom code and markup, including third party libraries, in your own namespace.
Important: Custom code must not be used to access the NetSuite DOM.
Developers must use SuiteScript APIs to access NetSuite UI components.
■ Use Subresource Integrity when you include content from external sources in Inline HTML
fields. For more information, see Subresource Integrity.
Testing ■ Good code is well-tested. Testing serves as an executable specification of the code and
examples of its use.
■ Always thoroughly test your code before using it on your live NetSuite data.
■ If the same script is used across multiple forms, ensure that you test any changes to the
code for each form that the code is associated with.
■ During testing, the Deployment Status should be Testing to limit the script execution to
only the script owner. If several users are testing a script (or if a Sandbox Account is being
used), the Deployment Status can be set to Released, but you must be sure to choose the
appropriate Audience so that the script doesn't execute for users who aren't involved in the
testing process. For production, the Deployment Status should set be Released. Again, it's
critical to set the appropriate Audience so that the script doesn't execute for unintended
users.
■ During testing, the Log Level should be set to Debug.
Logging ■ Log messages in the script should make business sense; include the record id, record type
and other important details in your log messages. Each log message should provide a clear
picture of the functionality that the script is designed to achieve.
■ Key steps in each script should be logged as Audit.
■ Proper logging adds to the readability of the code and also significant on issue/error
debugging.
■ During testing, the Log Level should be set to Debug. For a Production Deployment, the Log
Level should be set to Audit. Note that if there are production issues that require diagnosis/
debugging, the Deployment Log Level can be set back to Debug.
Other ■ Consider the time zone that your scripts must use. By default, server scripts use the time
zone that is specified in your NetSuite account. Be sure to convert your time values to the
correct time zone before you use them, if necessary.
■ Consider field limits and translation when creating your scripts. Fields that use special
characters used in some languages may support fewer characters than the field limit
specified. For example, the Reference No. field (tranid) supports 45 English characters, but
supports fewer Chinese characters.
■ Be sure to use BigInt values in your scripts to avoid potential errors. Integers larger than
MAX_SAFE_INTEGER and smaller than MIN_SAFE_INTEGER must be enclosed in quotations or
appended with 'n' at the end of the integer literal. For more information about BigInt values,
see BigInt.
You can also refer to the following Internet resources for JavaScript coding best practices:
The following are best practices for both form-level and record-level client SuiteScript development.
General ■ Use global (record-level) client scripts for more flexible deployment models
(include in a bundle or SuiteCloud project) than client scripts attached to
forms.
Advanced Employee Permissions ■ When the Advanced Employee Permissions feature is enabled, the search
columns available to users is also dependent on the permissions assigned
to the role.
■ When the Advanced Employee Permissions feature is enabled, the
fields and sublists a user has access to can change depending on which
employee is being viewed or edited. This is different from other records in
NetSuite, where permissions granted to a role determines what the role
can see for every instance of that record. In general, scripts should always
verify that a field exists before trying to do something with it. Simply calling
functions and methods that interact with fields before checking whether
the field is there may result in inconsistent behavior. For example, the
department field is permitted on the employee record. When you verify
that the field exists and you don't have access, a null value is returned, and
if the field is empty, an empty string is returned.
Unsafe Practice Example
To detect if your role has access to a field for a specific employee, load the
employee record object and call getFields(). If the field exists and you do
have access a true value is returned. In the below example, the user has
access to the department field for the employee with ID: 115.
Editing sublists ■ When you are editing the current line of a sublist and a nested client
script is triggered (for example, when a fieldChanged script is triggered
by changing a value in the current sublist line), make sure that the nested
script doesn't select a different line of the same machine as the current
line. Otherwise, the changes made in the parent script may be lost.
Execution contexts ■ Use execution context filtering to specify how and when a client script is
executed. Execution contexts provide information about how a script is
triggered to execute. For example, a script can be triggered in response
to an action in the NetSuite application, or an action occurring in another
context, such as a web services integration. You can use execution context
filtering to ensure that your scripts are triggered only when necessary. For
more information, see the help topic Execution Contexts.
setValue and setText methods ■ Methods that set values accept raw data of a specific type and don't
require formatting or parsing. Methods that set text accept strings but can
conform to a user-specified format. For example, when setting a numerical
field type, setValue() accepts any number, and setText() accepts a string
in a specified format, such as “2,000.39” or “2.00,39”. When setting a date
field type, setValue() accepts any Date object, and setText() accepts a
string in a specified format, such as “6/9/2016” or “9/6/2016”.
Debugging ■ When debugging client scripts, you can insert a debugger; statement in
your script, and execution will stop when this statement is reached:
function runMe() {
var k = 1;
k *= (k + 9);
debugger;
console.log(k);
}
When your script stops at the debugger; statement, you can examine your
script properties and variables using the debugging tools in your browser.
■ When debugging client scripts, some scripts might be minified. Minified
scripts have all unnecessary characters removed, including white space
characters, new line characters, and so on. Minifying scripts reduces the
amount of data that needs to be processed and reduces file size, but it can
also make scripts difficult to read. You can use your browser to de-minify
scripts so that they’re more readable. To learn how to de-minify scripts, see
the documentation for your browser.
Testing ■ When testing form-level client scripts, use Ctrl-Refresh to clear your
browser cache and ensure that the latest scripts are being executed.
Client Scripts in SuiteApps and ■ If you need to include client scripts in a SuiteBundle or a SuiteApp, don't
Bundles enable the Hide in SuiteBundle preference on the client script's file record.
The following are best practices for working with map/reduce scripts.
If you are concerned about potential issues with these limits, review
your script to make sure that your map and reduce functions are
relatively lightweight. Your map and reduce functions shouldn't include
a long or complex series of actions. For example, consider a situation
in which your map or reduce function loads and saves multiple records
all at the same time. This approach might cause an issue with the limits
described above. If your getInputData function returns a list of record
IDs, a better approach might be to use the map function to load each
record, update fields on the record, and save it.
Passing In the getInputData stage, your script must return an object that can
search data to be transformed into a list of key-value pairs. A common approach is to
getInputData use a search. If you decide to use this technique, note that you should
have your function return either a search.Search object or an object
reference to a saved search. By contrast, if you execute a search within
the getInputData function and return the results (for example, as an
array), there is a greater risk that the search will time out.
In both cases, the time limit available to the search is more generous
than it would be for a search executed within the function.
function getInputData()
{
return search.create({
type: record.Type.INVOICE,
filters: [['status', search.Operator.IS, 'open']],
columns: ['entity'],
title: 'Open Invoice Search'
});
}
...
function getInputData {
{
// Reference a saved search with internal ID 1234.
return {
type: 'search',
id: 1234
};
}
...
For information about additional ways to return data, see the help topic
getInputData(inputContext).
Handling restarts When a job is restarted, there is an inherent risk of data duplication.
Every map/reduce script should be written in such a way that each
entry point function checks to see whether the function has been
previously invoked. To do this, use the context.isRestarted property,
which exists for every map/reduce entry point. If the function has been
restarted, the script should provide any logic needed to avoid duplicate
processing. For examples, see the help topic Adding Logic to Handle
Map/Reduce Restarts.
Buffer size When you deploy a script, the deployment record includes a field called
Buffer Size. The default value of this field is 1. In general, you should
leave this value set to the default.
The Buffer Size field controls how many key-value pairs are flagged for
processing at one time, and how frequently a map or reduce job saves
data about its progress. Setting this field to a higher value may have
a small performance advantage. However, the disadvantage is that, if
the job is interrupted by an application server restart, there is a greater
likelihood of one or more key-value pairs being processed twice. For
that reason, you should leave this value set to 1, particularly if the script
is processing records.
For more details on this field, see the help topic Buffer Size.
The following are best practices for scheduled scripts. Also see the help topic Scheduled Script Handling
of Server Restarts.
General ■ Scheduled deployments and Not Scheduled deployments are executed from the same
processor pool. Keep this in mind as you deploy multiple scheduled scripts because
the amount of pending script instances is the ultimate bottleneck for scheduled script
execution throughput.
■ Create Not Scheduled deployments based on the anticipated number of simultaneous
calls to this script and approximate execution time of the script.
■ Although there is no restriction on the number of Not Scheduled scripts that can be
placed into the processing pool, too many pending scripts may create a backlog and
compromise system performance. Because only one script can be run in a processor at a
time, you shouldn't overload the system.
■ If you want to deploy scheduled scripts that are scheduled to run hourly on a 24 hour
basis, the following sample values should be set on the Script Deployment page:
□ Deployed =checked
□ Daily Event =[radio button enabled]
□ Repeat every 1 day
□ Start Date =[today's date]
□ Start Time =12:00 am
□ Repeat =every hour
□ End By =[blank]
□ No End Date =checked
□ Status =Scheduled
□ Log Level =Error
□ Execute as Role =Set to Administrator
If the Start Time is set to any other time than 12:00 am (for example, set to 2:00 pm), the
script will start at 2:00 pm, but then finish its hourly execution at 12:00 am. It won't resume
until the next day at 2:00 pm.
■ When possible, schedule your deployments during the hours of 2 AM to 6 AM PST.
Deployments scheduled for submission during the hours of 6 AM to 6 PM PST may not run
as quickly due to high database activity.
Deployments that ■ If you don't have an account with SuiteCloud Plus, all Scheduled deployments and Not
continue to use Scheduled deployments that continue to use queues are executed from the same queue.
queues If you deploy multiple scheduled scripts that continue to use queues, your queue size is the
ultimate bottleneck for scheduled script execution throughput. For additional information,
see the help topic Scheduled Script Deployments that Continue to Use Queues.
■ Although there is no restriction on the number of Not Scheduled scripts that can be
submitted to SuiteCloud Processors, too many waiting scripts may create a backlog and
compromise system performance. Because only one script can be run at a time, you
shouldn't overload the system.
■ Although there is no restriction on the number of Not Scheduled scripts that can be
placed into the processing pool, too many pending scripts may create a backlog and
compromise system performance. Because only one script can be run in a processor at a
time, you shouldn't overload the system.
Scheduled script vs ■ In general, you should use a map/reduce script rather than a scheduled script for any
Map/Reduce script scenario where you want to process multiple records, and where your logic can be
separated into relatively lightweight segments. However, a map/reduce script isn't as well
suited to situations where you want to enact a long, complex function for each part of your
data set.
■ Map/reduce scripts can be run manually or on a schedule, just like scheduled scripts.
However, map/reduce scripts offer several advantages over scheduled scripts. One
advantage is that, if a map/reduce job violates certain aspects of NetSuite governance,
the map/reduce framework automatically causes the job to yield and its work to be
rescheduled, without disruption to the script. However, be aware that some aspects of
map/reduce governance can't be handled through automatic yielding.
■ SuiteScript 2.x scheduled scripts don't support recovery points or yielding, so use map/
reduce scripts for large data processing. If you need to process a large amount of data or a
large number of records, use a map/reduce script instead. The map/reduce script type has
built in yielding and can be submitted for processing in the same ways as scheduled scripts.
For information about map/reduce scripts, see the help topic SuiteScript 2.x Map/Reduce
Script Type.
The following are best practices for Suitelet development using UI objects and custom UI.
General ■ Suitelets are ideal for generating NetSuite pages (forms, lists), returning data (XML, text), and
redirecting requests.
■ Limit the number of UI objects on a page: less than 100 rows for sublists, less than 100
options for on demand select fields, and less than 200 rows for lists.
HTML ■ Try using inline HTML fields embedded on the form before implementing a full custom HTML
page route.
■ Use Subresource Integrity when you include content from external sources in Inline HTML
fields. For more information, see Subresource Integrity.
iFrames ■ Append “ifrmcntnr=T” to the external URL when embedding in iFrame especially if you
are using the Firefox browser. (For more about NetSuite and iFrame, see the help topic
Embedding an Online Form in your Website Page.)
User credentials ■ When building a custom UI outside of the standard NetSuite UI (such as building a custom
mobile page using Suitelet), use the N/auth Module and N/crypto Module to help users
manage their credentials within the custom UI.
Calling a Suitelet ■ When calling a Suitelet using its external URL, escape the parameter values to avoid
and redirection cross-site scripting injections, for example, by converting the appropriate characters to HTML
entities.
■ For access or redirect to a Suitelet from another script, use url.resolveDomain(options) to
discover the URL instead of hard-coding the URL.
Advanced ■ When the Advanced Employee Permissions feature is enabled, keep the following in mind:
Employee
□ To avoid inadvertently exposing employee data, use caution when running Suitelets or
Permissions
Restlets as an administrator. A user with a role that has limited access to the employee
record can access a Suitelet or Restlet that runs as an administrator. Depending on how
the Suitelet or Restlet is written, the user may have access to employee information that
they would otherwise not see.
□ Use caution when setting up Suitelets and Restlets to give access to users without having
to log in since it could potentially expose employee information in uncontrolled ways.
Deployment ■ Deploy Suitelets as “Available without Login” only if necessary (no user context, login
performance overhead). (See Setting Available Without Login.)
The following are best practices for developing user event scripts.
General ■ For critical business logic, use a scheduled script to clean up after user events in case of errors.
■ Don't try to execute a user event script from another one -instead, create a module with
common code.
■ Make sure that the user event script doesn't access any sensitive field values.
Context ■ Use the type argument, the context object, and context.UserEventType enum to define and
limit the scope of your user event logic. See the help topic context.UserEventType.
Entry points ■ For operations that depend on on the submitted record being committed to the database
should happen in an afterSubmit script.
■ When updating transaction line items in a beforeSubmit script, ensure that the line item totals,
net taxes, and discounts are equal to the summarytotal, discounttotal, shippingtotal, and
taxtotal amounts.
■ Avoid assigning too many functions to one record type, as it can slow things down. This
could negatively affect the user experience with that record type. For example, if there are
ten beforeLoad scripts that must complete their execution before the record loads into the
browser, the time needed to load the record may increase significantly. Be aware of the
number of user events scripts used, including bundled user event scripts.
■ Use beforeSubmit to update fields or change the record before it's submitted.
■ Perform all post-processing operations of the current record on an afterSubmit event.
Storing values ■ If you want to store a value during a beforeLoad operation and then read that value during
an afterSubmit operation in the same script, consider using a hidden custom field to store
the value. You can add a hidden custom field to the form and store your value during
the beforeLoad operation, and you can retrieve the value from the same field during the
afterSubmit operation.
Execution ■ Use execution context filtering to control how and when a user event script is executed.
contexts Execution contexts provide information about how a script is triggered. For example, a script
can be triggered in response to an action in the NetSuite application, or an action occurring in
another context, such as a web services integration. You can use execution context filtering to
ensure that your scripts are triggered only when necessary. For more information, see the help
topic Execution Contexts.
Performance ■ Try to keep user event script execution under 5 seconds, as they run frequently. You can
use the Application Performance Management (APM) SuiteApp to test the performance of
your scripts deployed on a specific record type. See the help topic Application Performance
Management (APM).
Debugging ■ To debug a client script, include a debugger; statement as the first line in the script. When
execution reaches that statement, you can examine your script properties and variables
using the debugging tools in your browser. You can also use the debugger; statement in
the SuiteScript Debugger to help you debug server scripts. For more information about the
SuiteScript Debugger, see SuiteScript Debugger.
Hosted websites ■ Activities (user events) on a hosted website can trigger server SuiteScripts. In addition to
sales orders, scripts on case records and customer records also execute in response to web
activities.
Write your scripts with performance in mind to get the best results. This is especially important for your
custom scripts. You can see if there are custom scripts in your account at Customization > Scripting >
Scripts. The following guidelines are suggested to optimize script performance:
■ Use inline editable child custom records whenever your use case calls for batch processing of multiple
related/child records during user events on the parent record. (See the help topic Custom Child
Record Sublists in the NetSuite Help Center.)
Scripting Searches
■ Optimize your search filters and columns to get faster results by filtering inactive records, using
shorter date ranges, and removing unnecessary columns.
■ Use faster operators such as starts with/between/withi instead of contains/formulas.
■ Remove unused columns from your search results. Place any lines that add columns to search results
in a comment. Then the returned values aren't used by the succeeding script logic.
■ Wherever possible, combine searches for the same record into one main search with merged filters to
improve performance by minimizing search instances.
You should take certain measures to ensure your SuiteScript script runs safely and securely. This includes
the use of user credentials and executing scripts using a specific role, particularly when working with
sensitive data. In general, you should follow these guidelines:
User passwords ■ Don't hard-code any passwords in scripts. Using plain text or other unencrypted
user credentials is unsafe and can pose a security threat. Whenever possible, use
Token-based Authentication (TBA) or OAuth2.0 to specify user credentials.
■ Plaintext passwords can be used with SFTP, certificates, and other areas, however
NetSuite always gives the customer the option to use encrypted credential (GUID)
instead.
Script Deployment Deploy scripts to run as administrator only if necessary to reduce security risks and
performance issues. See Executing Scripts Using a Specific Role.
Script parameters For security reasons, don't include confidential information in script parameters.
Information saved in script parameters can be indexed by search engines and therefore
be viewable by the public. This means, for example, that the information could be found in
Google searches. For more information, see Creating Script Parameters Overview.
SuiteScript 2.x RESTlet The URLS for accessing RESTlets are protected by TLS encryption. Only requests sent
Script Type using TLS encryption are granted access. For more information, see the help topic
Supported TLS Protocol and Cipher Suites.
SuiteScript 2.x Suitelet ■ Deploy Suitelets as “Available without Login” only if necessary, such as when there is
Script Type no user context or due to login performance overhead. See Setting Available Without
Login.)
■ When building custom UI objects outside of the standard UI, such as when building
a custom mobile page using a Suitelet, you can use the N/auth Module to help users
manage their credentials within the custom UI.
SuiteScript 2.x User Event To prevent users from accessing sensitive information, such as password and credit card
Script Type data, the following internal field IDs cannot be read in beforeSubmit entry point scripts for
external role users:
■ password
■ password2
■ ccunumber (on the sales order record)
■ ccsecuritycode (on the sales order record)
External role users include shoppers, online form users and other anonymous users,
customer center users, etc.
N/auth Module Be extremely careful when using the N/auth module to change an email or user
password. Both the auth.changeEmail(options) and auth.changePassword(options)
methods allow you to include a plaintext string for the password.
N/http Module and N/ For security purposes, NetSuite blocks some headers from use in HTTP and HTTPS calls.
https Module For a list of blocked headers, see the help topic HTTP Header Information
N/https Module Plaintext user credentials can be included in HTTPS request parameters or in the body.
Using plain text or other unencrypted user credentials is unsafe and can pose a security
N/query Module When working with credit cards, you can retrieve only the encrypted version of the credit
card number, at most. You may not be able to retrieve and credit card number data.
Content from external Use Subresource Integrity when you include content from external sources in Inline
sources HTML fields. For more information, see Subresource Integrity.
SuiteScript Debugger
Applies to: SuiteScript 1.0 | SuiteScript 2.x | SuiteCloud Developer
NetSuite provides built-in capabilities to enable you to debug your SuiteScript 1.0, SuiteScript 2.0,
and SuiteScript 2.1 scripts. In this set of help topics, the debugger used to debug SuiteScript 1.0 and
SuiteScript 2.0 scripts is called the Script Debugger, while the debugger used to debug SuiteScript 2.1
scripts is called the 2.1 Script Debugger. To use the Script Debugger or the 2.1 Script Debugger, you must
be using a role with SuiteScript permission (Full level).
Note: If you are using SuiteScript 1.0 for your scripts, consider converting these scripts to
SuiteScript 2.0 or SuiteScript 2.1 scripts. Use SuiteScript 2.0 to take advantage of new features,
APIs, and functionality enhancements. SuiteScript 2.1 includes a new runtime engine which
may improve script performance, new language capabilities and functionality to support future
editions of the ECMAScript specification, such as support for the spread operator, classes,
and destructuring. For more information, see the help topics SuiteScript 2.x Advantages and
SuiteScript 2.1.
SuiteScript provides a script debugger for SuiteScript 1.0, SuiteScript 2.0, and SuiteScript 2.1 server
scripts, core plug-in implementations, and on-demand debugging.
Important: You cannot use the SuiteScript Debugger to debug SuiteScript 2.1 scripts. You can
still test critical parts of your script in the SuiteScript Debugger as a SuiteScript 2.0 script before
you run the script as a SuiteScript 2.1 script. For more information about SuiteScript 2.1, see the
help topic SuiteScript 2.1.
SuiteScript 2.1 scripts can be debugged with the new 2.1 Script Debugger. This debugger uses Chrome
DevTools directly within NetSuite to allow users to debug their scripts using functionality that is similar to
debugging JavaScript in the Google Chrome browser.
Client scripts cannot be debugged using the SuiteScript Debugger, but they can be debugged using
the tools available for your browser. To debug client scripts, you should use the Chrome DevTools for
Chrome and the Firebug debugger for Firefox. For additional information about these tools, see the
documentation provided with each browser.
Note: Currently, only one script can be debugged at a time in a given debug session, regardless
of the version of the script.
The following table shows which server script types are supported in each debugger. On-demand
debugging is also supported. Client scripts are debugged on the client browser.
Script Type Script Debugger Script Debugger (SuiteScript 2.1 Script Debugger
(SuiteScript 1.0) 2.0) (SuiteScript 2.1)
Bundle Installation ✓ ✓ —
Map/Reduce — — —
Mass Update ✓ ✓ —
Portlet ✓ ✓ —
RESTlet ✓ ✓ —
Scheduled ✓ ✓ ✓
Suitelet ✓ ✓ ✓
User Event ✓ ✓ ✓
Workflow Action ✓ ✓ —
Custom Plug-in ✓ ✓ —
The following table shows which custom plug-ins are supported in each debugger. Support for SuiteScript
2.1 scripts will increase in future releases.
GL Plugin ✓ —
Payment Gateway ✓ —
Consolidated Rate ✓ —
Adjustor
Promotions ✓ —
Tax Calculation ✓ —
Shipping Partners ✓ ✓
Email Capture ✓ —
Bank Connectivity ✓ —
Test Plugin ✓ ✓
For more information about using each debugger, see the following help topics:
■ Debugging Overview
■ Debugging SuiteScript 1.0 and SuiteScript 2.0 Scripts
■ Debugging SuiteScript 2.1 Scripts
Debugging Overview
Applies to: SuiteScript 1.0 | SuiteScript 2.x | SuiteCloud Developer
■ Debugging Modes
■ The Debugger Domain
■ Terms Related to Debugging
Note: To use the Script Debugger and the 2.1 Script Debugger, you must be using a role with
SuiteScript permission (Full level).
Debugging Modes
The Script Debugger and the 2.1 Script Debugger both provide two debugging modes:
■ On-demand debugging of scripts and code samples: With on-demand debugging, you can debug
a new script or a code sample that does not have a defined Script Deployment. Scripts that do not
require any form/record-specific interaction are good candidates for on-demand debugging. For more
information, see On-Demand Debugging of SuiteScript 1.0 and SuiteScript 2.0 Scripts and On-Demand
Debugging of SuiteScript 2.1 Scripts.
■ Debugging deployed scripts: With deployed debugging, you can select an existing script or core
plug-in implementation that already has a defined Script Deployment or Plug-in Implementation
record. To debug deployed scripts, you must be the script owner, and the status of your script or
core plug-in implementation must be set to Testing. For more information, see Debugging Deployed
SuiteScript 1.0 and SuiteScript 2.0 Server Scripts and Debugging Deployed SuiteScript 2.1 Server
Scripts.
Important: Any changes you make to your account when on this Debugger domain will affect
the data in your production account. For example, if you execute a script in the Debugger that
creates a new record, that record will appear in your production account.
Note: You may experience a decrease in performance when working on Debugger domains.
To access the debugger, go to Customization > Scripting > Script Debugger. The Debugger domain is
available from a production account or a release preview account. If you are already logged in to your
NetSuite account, you will not need to enter you account information again to access the Debugger
domain.
When you are logged in to the Debugger domain, you will see the Debugger logo at the top of the page:
When you are in the Debugger domain, you can debug SuiteScript 1.0, SuiteScript 2.0, and SuiteScript 2.1
scripts if the following requirements are met:
■ You must have scripting permission. See Setting Roles and Permissions for SuiteScript for more
information.
■ You must be the assigned owner of the script (as indicated on the script record).
■ If you are debugging a script that already has a defined script deployment, the script must be in
Testing mode before it can be loaded into the debugger. If you want to debug a script that has already
been released into production, you must change the script's status from Released to Testing on the
Script Deployment page. See Setting Script Deployment Status for more information about the script
deployment status.
Client scripts can be debugged using the tools available in your browser. Both form-level and record-level
client scripts should be tested on the form/record they run against.
If a bundled script has been installed into your account and the script has been marked as hidden, you
will not be able to debug this script.
Be aware that the Script Debugger and the 2.1 Script Debugger are not any of the following:
Term Definition
Call Stack A stack (most recent on top) of all the active functions (and their local variables) called up
until the current line of execution.
JavaScript Debugging The pane, normally on the right side of the Chrome DevTools tab (opened for SuiteScript
Pane 2.1 debugging), which displays breakpoints, watches, variables, and the call stack, and
includes execution control buttons.
Line Break Point A user-selected line in source code where program halts execution.
Minify/de-minify Minified code has had white space and other characters removed from display, so the
entire script appears as one long line. This can occur when using the 2.1 Script Debugger.
Minified code can be de-minified from within the Debugger. See Using Chrome DevTools.
User Event Break Point A user event script where program execution should be paused. The user event must be
invoked during script execution for the break point to function.
Watch A variable or expression that is monitored throughout the program's execution in the
current scope.
SuiteScript 1.0 and SuiteScript 2.0 scripts are debugged in the Script Debugger. The Script Debugger
enables you to debug SuiteScript 1.0 and SuiteScript 2.0 server scripts and core plug-in implementations,
and can be used for on-demand debugging.
Note: To use the Script Debugger and the 2.1 Script Debugger, you must be using a role with
SuiteScript permission (Full level).
The following help topics teach you how to use the Script Debugger:
The Script Debugger includes several buttons for controlling the execution of a script and several tabs for
viewing data during script execution. The Script Debugger UI includes a script area, buttons and tabs.
For an example of how to use the Script Debugger buttons and tabs, see Example Use of the Script
Debugger Buttons and Tabs.
The Script Debugger page includes five buttons to allow you to step through and execute your script:
These buttons can be used to control/resume script execution when the debugger stops at a particular
line. Note that each button also has an associated keyboard shortcut.
■ Step Over
Resumes execution from the current line and stops at the next line (even if the current line is a
function call). Keyboard shortcut is space.
■ Step Into
Resumes execution from the current line and stops at the first line in any function call made from the
current line. Keyboard shortcut is 'i'.
■ Step Out
Resumes execution from the current line until the end of the current function, and stops at the first
line following the line from where this function was called -or-until the next break point -or-until the
program terminates (either by error or by normal completion). Keyboard shortcut is 'o'.
■ Continue
Resumes program execution from the current line until the next break point -or-until the program
terminates. Keyboard shortcut is shift+space.
■ Cancel
Aborts execution of the program from the current line. Keyboard shortcut is 'q'.
The Script Debugger page includes several subtabs to allow you to access information within your script
as the script runs:
■ Execution Log
■ Local Variables
■ Watches
■ Evaluate Expressions
■ Break Points
Execution Log
Note: The Execution Log subtab is not used for SuiteScript 2.1 scripts. Logging of SuiteScript
2.1 scripts is done on the Chrome DevTools debugger console. For more information about
debugging SuiteScript 2.1 scripts, see Introduction to Chrome DevTools for SuiteScript 2.1 Script
Debugging.
The Execution Log subtab shows all execution logs created by the currently executing program, including
errors logged by the system. The execution log details that appear on this subtab are the same details
that would normally appear in the Execution Log on the Script Deployment page. However, when working
in the debugger all script execution details appear on the Execution Log subtab on the Script Debugger
page; these details will NOT appear on the Execution Log subtab of the Script Deployment page.
The type, subject, details, and timestamp are displayed on the Execution Log subtab. The timestamp is
recorded on the server. It is converted to the current user's time zone for display.
Log details are collapsed by default but can be seen by clicking the expand/collapse icon. Note that the
subtab is automatically cleared at the start of each debugging session.
Local Variables
Note: The Local Variables subtab is not used for SuiteScript 2.1 scripts. Logging of SuiteScript 2.1
scripts is done on the Chrome DevTools debugger console. See Introduction to Chrome DevTools
for SuiteScript 2.1 Script Debugging for more information about debugging SuiteScript 2.1 scripts.
The Local Variables subtab shows a list of all local variables (primitives, objects, and NetSuite objects)
currently in scope. Note that for NetSuite objects, all properties are private, even though they can be seen
on the Local Variables subtab. Do not try to reference these properties directly in your script. Use the
appropriate getter/setter functions instead.
The Local Variables subtab includes a call stack that shows the current execution stack of the program.
The function call and current line number for that function are included in the list. Use the Call Stack
list to switch to different call stacks to view different local variables. In addition, watch expressions and
expression evaluations are automatically performed in the context specified by this field.
Important: Due to performance considerations, the member display limit for all variables is
1000. In addition, only the first 500 characters of a String are displayed. For large variables, use a
watch to see the full member display (see Watches for additional information).
Watches
Note: The Watches subtab is not used for SuiteScript 2.1 scripts. Logging of SuiteScript
2.1 scripts is done on the Chrome DevTools debugger console. For more information about
debugging SuiteScript 2.1 scripts, see Introduction to Chrome DevTools for SuiteScript 2.1 Script
Debugging.
The Watches subtab is where you can add or remove variables and expressions to a list that is maintained
and kept up-to-date (“watched”) throughout the execution of a script.
The variables and expressions are always evaluated in the current call stack. This means that by default
they are evaluated at the current line of script execution. However, if you switch to a different function in
the call stack, they are re-evaluated at that location.
■ To add a variable or an expression, type it into the Add Watch field and press the Enter key.
■ To remove a watched variable or expression, click on the red x icon to the left of the expression.
■ To browse sub-properties of a user-defined object, an array, or a NetSuite object expression, click the
expand/collapse icon next to the property name.
Note that you can use the Watches subtab to view object properties using a command-line interface. Any
property that is viewable from the property browser can be added as a watch expression by referencing
the property using dot ( . ) notation, even if the property is private in the script. For example, the ID of a
record object (referenced by a variable called record ) by typing record .id in the Add Watch field.
Evaluate Expressions
Note: The Evaluate Expressions subtab is not used for SuiteScript 2.1 scripts. Logging of
SuiteScript 2.1 scripts is done on the Chrome DevTools debugger console. For more information
about debugging SuiteScript 2.1 scripts, see Introduction to Chrome DevTools for SuiteScript 2.1
Script Debugging.
Use the Evaluate Expressions subtab to execute code at break points during the current program. Doing
so provides access to the program's state, allowing you to modify the state of the program.
Enter an expression in the Evaluate Expression field and press the Enter key to evaluate the expression
at the selected call stack. The results of an evaluated expression (if any) is displayed in the window below.
Any change to the program's state is immediately reflected in the Local Variables and Watches subtabs.
Break Points
Note: The Break Points subtab is not used for SuiteScript 2.1 scripts. Logging of SuiteScript
2.1 scripts is done on the Chrome DevTools debugger console. For more information about
debugging SuiteScript 2.1 scripts, see Introduction to Chrome DevTools for SuiteScript 2.1 Script
Debugging.
The Break Points subtab shows all your instruction-level (line) break points as well as your user event
break points. Note that you can add user event break points by selecting user events from the Break on
User Event list.
You can set break points in your code using the Script Debugger code window. By setting breakpoints,
you can execute your code up to a certain point, and then halt the execution at the break point and
examine the current state of the execution.
1. Click between the line number and the line of code to add a breakpoint:
2. To remove a break point, click the break point icon as it appears in the code. You can also remove
a break point by clicking the red x icon next to the break point, as it appears on the Break Points
tab.
Note that when you debug deployed scripts, you can set break points at each user event in your
script. User events possibly invokable during script execution where the program halts execution.
The following example shows how to debug a script using the execute, step over, and step into buttons.
This example also shows how to use the Execution Log, Local Variables, and Watches tabs.
Note: The code in this example assumes you have at least two customers with an entityId that
includes 'Jack'.
/** * @NApiVersion 2.x */ require (['N/search'], function (search) { var mySearch = search.create({ type: search.Type.CUS
TOMER, columns: ['entityid', 'firstname', 'lastname', 'salesrep'], filters: ['entityid', 'contains', 'Jack'] }); var
myResultSet = mySearch.run(); var resultRange = myResultSet.getRange({ start: 0, end: 50 }); for (var i = 0; i < resul
tRange.length; i++) { log.debug(resultRange[i]); }
});
6. Set a breakpoint at the var myResultSet =mySearch.run() line by clicking between the line
number (11) and the code line. Notice that when you add or remove a breakpoint, “Running
Script” is briefly displayed:
However, the script is not running. But, the breakpoint is being inserted into the proper location.
7. Set another breakpoint at the for line (line 18). The two breakpoints are shown like this:
8. Click the Continue button to execute the script to the first breakpoint.
9. When the breakpoint is reached, the debugger pauses execution and highlights the line:
10. Click the Step Over button to execute the mySearch.run() line to get your search results:
The debugger runs the search and pause at the next line of code:
11. While the debugger is paused, click the Local Variables subtab to view the value of the
myResultSet variable:
12. Click the Continue button to continue executing the script to the next breakpoint (line 18):
13. When the debugger pauses on line 18, click the Step Into button:
The debugger will execute the for line and pause at the first line in the for loop block of code,
which is the log.debug statement:
14. While the debugger is paused, add a watch for the resultRange variable to watch the variable
value update as the for loop. Enter resultRange into the Add Watch box on the Watches subtab
and press the Enter key to see the value.
15. Click the Continue button. The debugger executes one iteration of the for loop and will again
pause.
16. On the Watches tab, expand the resultRange variable to view its current value
17. Click the second breakpoint to remove it. You must remove the breakpoint so the debugger does
not pause at every iteration of the for loop. You can remove any breakpoint at anytime while the
debugger is paused.
18. Click the Continue button to finish executing the script.
When the script completes execution, the Execution Log subtab shows all your log.debug statements:
On-demand debugging is used for testing SuiteScript 1.0 or SuiteScript 2.0 scripts or code samples that
do not have a defined script deployment. On-demand debugging is not used for scripts that have a Script
record or defined deployment parameters set on the Script Deployment page. For information about
debugging deployed SuiteScript 1.0 and SuiteScript 2.0 scripts, see Debugging Deployed SuiteScript 1.0
and SuiteScript 2.0 Server Scripts.
Important: Any changes you make to your account when on this Debugger domain will
affect the data in your production account. For example, if you execute a script in the
Debugger that creates a new record, that record will appear in your production account.
2. Select the API Version — 1.0 or 2.0. (If you want to debug a SuiteScript 2.1 script, see On-Demand
Debugging of SuiteScript 2.1 Scripts).
3. Enter your code sample or script in the New Script text area. If your script is a 2.0 script and
includes a define statement, you will need to change that to a require statement to run the script
in the debugger. For more information, see the help topic SuiteScript 2.x Global Objects.
If you have already written your code in an IDE, copy and paste the code into the New Script text
area. If you modify your script in the debugger and you intend to save the changes, you must copy
the updated script from the debugger and paste it into your IDE.
4. Click Debug Script.
The script is immediately loaded into the debugger and the program's execution stops before
running the first line of executable code.
Important: Make sure you always have an executable call in your script; otherwise, the
script has nothing to execute and return.
5. With the script loaded into the debugger, you can step through each line to inspect local variables
and object properties. You can also add watches, evaluate expressions, and set break points. See
Script Debugger Interface for information about stepping into/out of functions, adding watches,
setting and removing break points, and evaluating expressions.
6. When execution of your script is complete, a Completed New Script Execution message appears.
You can either re-run the script (by clicking Re-run Script), or place the script into edit mode (by
clicking Switch to Editor) and continue debugging.
Script execution details are logged on the Execution Log subtab of the Script Debugger. You can also use
the N/log Module within your script to access methods for logging script execution details for all scripts.
See Using the Script Execution Log Tab to learn how SuiteScript 1.0 and SuiteScript 2.0 script execution
details are logged.
Deployed-mode debugging is for testing scripts or core plug-in implementations that have a defined
Script Deployment or Core Plug-in Implementation record.
Note: SuiteScript does not support read-only sublists. If you are debugging a script that loads
a record with a custom child record as a sublist, make sure the Allow Child Record Editing
setting is checked for the child record in Customization. If this box is not checked, the sublist is
read-only and will not load in the parent record. See the help topic Creating Custom Record Types
for additional information about creating custom records.
Important: Any changes you make to your account when on this Debugger domain will
affect the data in your production account. For example, if you execute a script in the
Debugger that creates a new record, that record will appear in your production account.
2. When you are on the Debugger domain, go to the applicable Script Deployment or Core Plug-in
Implementation record and verify that Status is set to Testing. If you want to debug a script or
core plug-in implementation that has already been released into production, you must change the
status from Released to Testing.
3. Verify that you are the assigned owner of the script or core plug-in implementation. You can only
debug a script or core plug-in implementation if you are the assigned owner.
4. To access the Script Debugger start page, use the appropriate option:
■ If you are on the Script Deployment page in View mode, click Debug.
■ If you are on the Script Deployment page in Edit mode, click Save and Debug.
■ If you are not on the Script Deployment page or you are debugging a core plug-in
implementation, you can access the debugger by going to Customization > Scripting > Script
Debugger.
5. On the Script Debugger page, select your API Version and then click Debug Existing. The list of
scripts will be filtered based on the selected API version.
The Debug Existing popup window opens and shows all server scripts and core plug-in
implementations available for debugging (see figure below) based on the selected API version.
Note that only scripts and core plug-in implementations whose statuses are set to Testing are
listed.
6. Select the script you want to debug and click Select and Close.
7. The Script Debugger page is updated with a Waiting for User Action status message. The debugger
is waiting for you to perform the action that is associated with the selected script or plug-in
implementation.
Note: Adding or updating records using CSV import may not trigger the debugging of
scripts because the CSV import may create or update records using a different user role or
entity. Remember, that you can only debug scripts if you are the assigned owner.
Note: You do not need to perform any user actions to load scheduled scripts into the
Debugger. Simply select your scheduled script from the Script Debugger popup window,
and then click Save and Close. The scheduled script automatically loads.
8. When the script is loaded into the debugger, it is shown on the Script Debugger page:
Note: The Debugger does not caption the user action during bulk processing, but the script is
executed and a log is created.
Important: You should perfrom user actions in another window or another tab on your
browser. This enables you to keep the Script Debugger page open so that you can see the script
or core plug-in implementation as it loads. To do this, right-click on the menu item (or other UI
element) and select Open Link in New Tab or Open Link in New Window.
With the script loaded into the Debugger, you can now step through each line to inspect local variables
and object properties. You can also add watches, evaluate expressions, and set break points. See Script
Debugger Interface for information about stepping into/out of functions, adding watches, setting and
removing break points, and evaluating expressions.
When execution of a script is complete in the debugger, you can either re-run it (by clicking Re-run
Script), or place it into edit mode (by clicking Switch to Editor) and continue debugging.
Important: If you modify any script or core plug-in implementation in the SuiteScript Debugger
and you intend to save the changes, you must copy the updated code from the Script Debugger
page and paste it into your IDE (or other editor). You must then re-load the updated file back into
the NetSuite File Cabinet.
Script execution details are logged on the Execution Log subtab of the Script Debugger. You can also use
the N/log Module within your script to access methods for logging script execution details for all scripts.
See Using the Script Execution Log Tab to learn how SuiteScript 1.0 and SuiteScript 2.0 script execution
details are logged.
The following tips may help you debug SuiteScript 1.0 and SuiteScript 2.0 scripts using the Script
Debugger:
■ Review the Execution Log subtab on the Script Debugger page to view all script messages and alerts,
including those indicating any script errors.
■ Execution metrics are shown on the Execution Log subtab of the Script Debugger page.
■ Use breakpoints to pause script execution at predetermined lines of code. Breakpoints are managed
on the Break Points subtab on the Script Debugger page. See Break Points for more information.
■ Use the Watch subtab on the Script Debugger page to see values of variables within your script and to
evaluate expressions on-the-fly. See Watches for more information.
■ Use the Evaluated Expressions subtab on the Script Debugger page to enter and evaluate
manually-entered expressions. See Evaluate Expressions for more information.
■ To cancel a debugging session without completing script execution, click the X button on the Script
Debugger page.
SuiteScript 2.1 scripts can be debugged with the new 2.1 Script Debugger. This debugger uses Chrome
DevTools directly within NetSuite to allow users to debug their scripts using functionality that is similar to
debugging JavaScript in the Google Chrome browser.
Note: To use the Script Debugger and the 2.1 Script Debugger, you must be using a role with
SuiteScript permission (Full level).
Note: The 2.1 Script Debugger is fully supported when using NetSuite in the Chrome browser.
Other browsers, such as Mozilla Firefox and Apple Safari, have limited or no support. Functionality
in those browsers is not guaranteed.
The following help topics teach you how to use the Script Debugger:
Script debugging is an important part of the holistic developer experience. Debugging with Chrome
DevTools is the most common way to debug JavaScript. In our effort to offer a modern coding experience
to our developers, we have developed the 2.1 Script Debugger using Chrome DevTools to allow users to
debug their scripts using similar functionality available when debugging JavaScript in the Google Chrome
browser.
The 2.1 Script Debugger is accessed the same way as the legacy Script Debugger used for SuiteScript
1.0 and SuiteScript 2.0 scripts. To use the 2.1 Script Debugger, select 2.1 as the API Version on the Script
Debugger page. When you click Debug Script, a new browser tab opens providing you with the Chrome
DevTools interface for debugging your script. Your script will be displayed on the new tab and you will be
able to pause/resume execution, set breakpoints, and step through your code line by line.
Note: Only SuiteScript 2.1 scripts can be debugged using the 2.1 Script Debugger. You cannot
use the 2.1 Script Debugger to debug SuiteScript 1.0 or SuiteScript 2.0 scripts.
In 2021.1, the following SuiteScript 2.1 server script types can be debugged:
■ Scheduled scripts
■ Suitelets
■ User event scripts
Debugging of SuiteScript 2.1 versions of other script types and core plug-in implementations is planned
to be supported in a future NetSuite release. Also, debugging "Hidden in SuiteBundle" files is not
currently supported. See the help topic Add the Bundle Installation Script File to the File Cabinet for
information about the Hide in SuiteBundle option for Bundle Installation scripts.
Note: Currently, only one script can be debugged at a time in a given debug session, regardless
of the version of the script. You cannot debug a SuiteScript 2.0 script at the same time as a
SuiteScript 2.1 script.
The following table lists the debugging capabilities provided by Chrome DevTools along with an indication
of whether the capability is supported in the 2.1 Script Debugger in the 2021.1 release. See Using
Chrome DevTools for instructions on each capability.
Edit code —
Searching ✓
Code coverage ✓
Set up a workspace —
Keyboard shortcuts ✓
See https://developers.google.com/web/tools/chrome-devtools/
shortcuts
The 2.1 Script Debugger provides a subset of the full functionality of the Chrome DevTools available
within the Chrome browser.
Note: Only SuiteScript 2.1 scripts can be debugged using the 2.1 Script Debugger. You cannot
use the 2.1 Script Debugger to debug SuiteScript 1.0 or SuiteScript 2.0 scripts.
Note: Some of the following information, provided as a summary of the Chrome DevTools as
it can be used in debugging JavaScript, is taken from Chrome DevTools. Refer to that site for
complete information.
Also refer to Debug JavaScript and JavaScript Reference for additional help specific to debugging
JavaScript code.
Chrome DevTools is a set of web developer tools built directly into the Google Chrome browser. Chrome
DevTools can help you edit pages on-the-fly and diagnose problems quickly. The JavaScript portion of the
Chrome DevTools site (JavaScript) includes a tutorial and video that teaches you all the things you can do
to debug your JavaScript code. Most of these are included in the 2.1 Script Debugger. See the 2.1 Script
Debugger Overview section for a list of capabilities provided in the 2.1 Script Debugger.
Tip: Use CTRL+SHIFT+I to access Chrome DevTools from within the Chrome browser. Note that
you do not have to do this when debugging SuiteScript because NetSuite automatically provides
the Chrome DevTools capability in a separate browser tab.
The following figure shows a sample Chrome DevTools Sources tab opened for debugging SuiteScript 2.1
scripts.
Note: Chrome DevTools for SuiteScript 2.1 scripts supports the Console and Sources tabs only.
Currently, there is no support for the Memory or Profiler tabs when debugging SuiteScript 2.1
scripts.
Note: NetSuite’s use of Chrome DevTools for SuiteScript 2.1 script debugging adheres to all
license parameters as described at Chrome DevTools License.
Set and remove breakpoints Breakpoints are shown in the Breakpoints section of the JavaScript debugging pane:
To set a breakpoint, click to the left of the line of code in the Source window where
you want the break to be set. A breakpoint marker is displayed:
Disable/re-enable To disable all breakpoints, click the disable breakpoints button: . A disabled
breakpoints breakpoint marker appears grayed-out:
To re-enable all breakpoints, click the re-enable breakpoints button: . Note that
break points must first be set to disable/re-enable them.
When all breakpoints are disabled, the breakpoints list is grayed out:
Step through code To step over a line of code, click the step over button: . The code pointer moves to
the next line.
To step into a line of code, click the step into button: . The code pointer moves
into the function. Note that you cannot step into a SuiteScript module. Clicking the
step into button when the code pointer is at a SuiteScript module will move the code
pointer to the next line, effectively skipping over the SuiteScript module.
To step out of a line of code, click the step out button: . The code pointer moves out
of the function to the line after the function call.
Pause and resume execution To pause execution, click the pause button: . When script debugging is paused, you
will see the Debugger paused message:
Restart execution from a line To restart execution from a point in the call stack:
within the call stack
1. Expand the Call Stack section of the JavaScript Debugging pane.
2. Click the line of code in the call stack where you want to resume execution.
3. Click the resume execution button:
View and edit local, closure, Values of SuiteScript and JavaScript objects can be viewed by expanding the Local,
and global properties Closure, or Global sections of the JavaScript debugging pane:
View current call stack To view the call stack, click the Call Stack header on the JavaScript debugging pane:
You can also select a point in the call stack and resume execution from that point.
Display the console The console can be displayed in the main debugger window or on the bottom pane of
the debugger by clicking the corresponding Console tab. Be aware that if you use the
Console tab on the left side of the debugger, the source window closes.
De-minify display of the script Sometimes source code will be displayed minified when it is displayed on the Sources
code tab:
This is often unreadable. You can de-minify the source (that is, add appropriate white
space and new lines) by using the button located at the bottom of the source
window.
Watch variable and Use the Watch window, on the JavaScript debugging pane, to see values of variables
expression values within your script and to evaluate expressions on-the-fly:
To add a variable or enter an expression to evaluate, click the plus (+) button on the
Watch window header and enter the variable name or expression. Notice in the above
example, the variable being watched is a SuiteScript object so all available members of
that object are displayed.
Chrome DevTools supports keyboard shortcuts for nearly all actions available in the debugger. See
Chrome DevTools Keyboard Shorcuts. And, your Chrome DevTools environment is retained between
debugging session. For instance, if you open the Console window the first time you debug a script,
Chrome DevTools will open with the Console window open in each subsequent debugging session.
On-demand debugging is for testing SuiteScript 2.1 scripts or code snippets that do not have a defined
script deployment. On-demand debugging is not for scripts that have a Script record or defined
deployment parameters (set on the Script Deployment page). See Debugging Deployed SuiteScript 2.1
Server Scripts for information about debugging deployed SuiteScript 2.1 scripts.
Note: The first time you use the 2.1 Script Debugger, you may get notification that the
popup window was blocked. To use the 2.1 Script Debugger, you must allow this popup
window. To do this, click the button on the right side and select to always allow popup
windows. You only need to do this one time. All future access to the 2.1 Script Debugger will
be immediate.
Note: When the Chrome DevTools tab opens, it may not show your code. Click the
resume script execution button. to access your code. If you code is still not displayed
in the Source window, click the :program line under the Call Stack section on the JavaScript
debugging pane.
5. You can now debug your code as desired. See Using Chrome DevTools for information about
debug actions you can perform. Use the console to view all log messages. Your code may also be
minified. Use the de-minify code button. ) to display your code in a readable manner.
See Tips for Debugging SuiteScript 2.1 Scripts for additional help when using the Debugger in on
demand mode for SuiteScript 2.1 scripts.
6. When execution of your code is complete, “Completed New Script Execution” is displayed on the
Script Debugger page above the script. You can close the Chrome DevTools tab at any time after
script execution is complete.
Note: When script execution is complete or when an error occurs during script execution, you
will see the message: Debugging connection was closed. Reason: Websocket disconnected. This
is a normal message. You can close the browser tab and return to the Script Debugger where you
can re-run your script or enter a new script for debugging.
Deployed-mode debugging is for testing scripts that have a defined Script Deployment record. Note that
plug-in implementations are not supported in 2021.1.
Note: Only SuiteScript 2.1 scripts can be debugged using the 2.1 Script Debugger. You cannot
use the 2.1 Script Debugger to debug SuiteScript 1.0 or SuiteScript 2.0 scripts.
In 2021.1, you can debug SuiteScript 2.1 scheduled scripts, Suitelets, and user event scripts using the 2.1
Debugger. See the following help topics for more information:
You can debug SuiteScript 2.1 scheduled scripts and Suitelets that are in File Cabinet and have a Script
Deployment record.
Note: SuiteScript does not support read-only sublists. If you are debugging a script that loads
a record with a custom child record as a sublist, make sure the Allow Child Record Editing
setting is checked for the child record in Customization. If this box is not checked, the sublist is
read-only and will not load in the parent record. See the help topic Creating Custom Record Types
for additional information about creating custom records.
1. Create your SuiteScript 2.1 scheduled script or Suitelet, upload it to the File Cabinet, and create a
Script Deployment record for it.
2. Go to Customization > Scripting > Script Debugger.
3. Select 2.1 in the API Version field.
4. Click Debug Existing Script. The Debug Existing popup window opens showing all deployed
SuiteScript 2.1 scripts.
5. Select your desired deployed script and click Select and Close.
6. The Script Debugger page updates displaying “Waiting for User Action” message above the
script. This means that it is waiting for you to perform the action associated with how the script is
deployed.
7. When you perform the necessary action, the “Waiting for devtools to attach” message is displayed
above the script on the Script Debugger page and a new browser tab opens for Chrome DevTools.
Note: The first time you use the 2.1 Script Debugger, you may get notification that the
popup window was blocked. To use the 2.1 Script Debugger, you must allow this popup
window. To do this, click the button on the right side and select to always allow popup
windows. You only need to do this one time. All future access to the 2.1 Script Debugger will
be immediate.
8. Your deployed script code is displayed on the new tab where you can debug as desired. A
“Debugging <script>.js” message is displayed on the Script Debugger page indicating that the
Chrome DevTools tab is ready for use.
9. The Debugger will automatically stop at the first line of your script, which is normally the define
or require statement. You can now debug your code as desired. See Using Chrome DevTools for
information about debug actions you can perform. Use the console to view all log messages. See
Tips for Debugging SuiteScript 2.1 Scripts for additional help when debugging scripts.
10. When execution of your code is complete, “Completed Deployed Script Execution” is displayed on
the Script Debugger page above the script. You can close the Chrome DevTools tab at any time
after script execution is complete.
Note: When script execution is complete or when an error occurs during script execution, you
will see the message: Debugging connection was closed. Reason: Websocket disconnected. This
is a normal message. You can close the browser tab and return to the Script Debugger where you
can re-run your script or enter a new script for debugging.
SuiteScript 2.1 user event scripts can be debugged using the 2.1 Debugger similar to other supported
server script types (scheduled scripts and Suitelets) as described in Debugging Deployed SuiteScript 2.1
Scheduled Scripts and Suitelets. However, because a user event script can have multiple entry points,
there are some special steps to take when debugging SuiteScript 2.1 user event scripts.
You can debug every entry point included in your SuiteScript 2.1 user event script within the same
browser session, however, you must reattach to Chrome DevTools for each entry point included in the
script.
Note: SuiteScript does not support read-only sublists. If you are debugging a script that loads
a record with a custom child record as a sublist, make sure the Allow Child Record Editing
setting is checked for the child record in Customization. If this box is not checked, the sublist is
read-only and will not load in the parent record. See the help topic Creating Custom Record Types
for additional information about creating custom records.
Following is an example of debugging a user event script deployed on the Customer record. You first
need to create the user event and start the debugger before you can debug the script.
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define (['N/record'], function (record) {
function beforeLoad(context) {
if (context.type !== context.UserEventType.CREATE)
return;
customerRecord.setValue('phone', '555-555-5555');
if (!customerRecord.getValue('salesrep')) {
customerRecord.setValue('salesrep', 59); // replace 59 with a value specific to your account
}
}
function beforeSubmit(context) {
if (context.type !== context.UserEventType.CREATE)
return;
function afterSubmit(context) {
if (context.type !== context.UserEventType.CREATE)
return;
if (customerRecord.getValue('salesrep')) {
var call = record.create({
type: record.Type.PHONE_CALL,
isDynamic: true
});
try {
var callId = call.save();
log.debug('Call record created successfully', 'Id: ' + callId);
} catch (e) {
log.error(e.name);
}
}
}
return {
beforeLoad: beforeLoad,
beforeSubmit: beforeSubmit,
afterSubmit: afterSubmit
}
});
2. Create a script record for your script. For this example, set the Name field to Debug Customer w/
2.1 UE and set the Applies To: field to Customer.
3. To have the script appear on the debugger tab, it must be executed by creating and saving a new
Customer record (List > Relationships > Customers > New).
4. Go to Customization > Scripting > Script Debugger.
5. Select Debug Existing and select the Debug Customer w/ 2.1 UE user event script.
6. Click Select and Close. The Script Debugger will wait for a user action to proceed:
1. Follow the steps above to create the user event script and start the debugger.
2. To trigger the beforeLoad entry point, either create a new Customer or edit an existing Customer.
3. When the customer record is loaded, a new Chrome DevTools tab opens in your browser showing
your user event script ready to be debugged using the 2.1 Debugger:
4. The execution of your script stops at the top of the script. You can now add breakpoints, watches,
etc. and begin debugging your script. You can also add a debugger; statement at the top of the
beforeLoad entry point code to specifically stop the execution of the script at that entry point.
5. When you have finished stepping over/playing through the last line of the beforeLoad entry point
code, the Script Debugger tab will show:
And you will see a message in the Chrome DevTools tab that indicates the debugging connection
was closed:
You do not need to click the Reconnect DevTools button on this message. If you want to reexecute
the beforeLoad entry point in your script, save the Customer record to restart the debugging
session
1. Go to Customization > Scripting > Script Debugger, or re-execute the script if you are already in the
Script Debugger from debugging the beforeLoad entry point.
2. Create a new Customer or edit an existing Customer. Do not save the record yet. You first need
to get ready to debug the script, as shown in the next steps, before clicking Save.
3. Select Debug Existing and select the Debug Customer w/ 2.1 UE user event script:
4. Click Select and Close. The Script Debugger will wait for a user action to proceed:
5. To trigger the beforeSubmit entry point, save the Customer record. A new Chrome DevTools
tab opens in your browser showing your user event script ready to be debugged using the 2.1
Debugger:
6. The execution of your script stops at the top of the script. You can now add breakpoints, watches,
etc. within the beforeSubmit entry point and begin debugging your script. You can also add
a ‘debugger;’ statement at the top of the beforeSubmit and afterSubmit entry point code to
specifically stop the execution of the script at that entry point.
7. After the last line of the beforeSubmit function executes, the following message will appear in the
Chrome DevTools tab:
Note: This reattach phase only appears if you have both a beforeSubmit and an
afterSubmit entry point in your user event script. If you have only the beforeSubmit entry
point or the afterSubmit entry point, your debugging session will end at the completion of
the entry point code.
8. To reattach the debugger and continue to debug your afterSubmit entry point code, click the
Reconnect DevTools button on the message. The Chrome DevTools tab will reload your script
and execution will stop at the beginning of the afterSubmit entry point code. You can now add
breakpoints, watches, etc. and begin debugging your script.
9. When you have finished stepping over/playing through the last line of the afterSubmit entry point
code, the Script Debugger tab will show:
And you will see a message in the Chrome DevTools tab that indicates the debugging connection
was closed:
You do not need to click the Reconnect DevTools button on this message. If you want to re-execute
the any entry point in your script, you will need to reload a customer record and follow the steps to
debug the beforeLoad entry point or to debug the beforeSubmit and afterSubmit entry points.
Note: Only SuiteScript 2.1 scripts can be debugged using the 2.1 Script Debugger. You cannot
use the 2.1 Script Debugger to debug SuiteScript 1.0 or SuiteScript 2.0 scripts.
The following tips may help you debug SuiteScript 2.1 scripts using the Chrome DevTools debugger:
■ If your script code appears minified (lacking white space and new line characters), you can use the
de-minify button. to change the display of the code so that it is readable.
■ Details normally displayed on the Execution Log of the Script Debugger page are shown on the
Chrome DevTools console when debugging SuiteScript 2.1 scripts.
■ Execution metrics for SuiteScript 2.1 scripts are shown in the Chrome DevTools console when the
script completes execution. These are general the same metrics displayed for SuiteScript 1.0 and
SuiteScript 2.0 scripts in the Script Debugger page and include script messages and alerts, including
script errors.
■ Use breakpoints to pause script execution at predetermined lines of code. Active breakpoints are
listed in the Breakpoints List in the JavaScript debugging pane (on the Chrome DevTools tab).
■ Use the Watch window on the JavaScript debugging pane to see values of variables within your script
and to evaluate expressions on-the-fly.
■ Use the Call Stack window on the JavaScript debugging pane to view different areas of your script. You
can also select a point in the call stack and resume execution from that point.
■ To cancel a debugging session without completing script execution, click the X button on the Script
Debugger page. The Chrome DevTools tab can be left opened or it can be closed. If you leave it open,
it will be used for the next debugging session. Note that simply closing the tab does not fully cancel
the current debugging session. You must use the red X button.
■ Each 2.1 debugging session has a timeout. If you do not perform any actions in the Chrome DevTools
debugger within the timeout period, your debug session will end. See Idle Timeouts.
Client scripts are executed on the client browser based on how they are deployed. To debug a client
script, use the debugging tools available on your browser. SuiteScript supports several browsers:
Each browser includes its own debugging tools. The following table includes links to documentation for
each browser.
Client scripts (both form-and record-level) should be tested on the form/record they run against. See the
help topic SuiteScript 2.x Client Script Entry Points and API for more information about triggering a client
script. Also see the help topic Record-Level and Form-Level Script Deployments for more information
about deploying a client script.
All browsers support common actions within their debugging environments. These actions including
stepping through or over code, setting breakpoints, and pausing/resume execution.
Important: To debug a client script, the script MUST include a ‘debugger;’ statement. Place
the ‘debugger;’ statement near the top of the script so that the debugger is invoked immediately
when the script is triggered. Execution will stop when the statement is reached, allowing you to
examine script properties and variables using the debugging tools in your browser.
1. Create, upload and deploy your client script. Note that to debug a client script, it must include a
'debugger;' statement. For example:
debugger;
var k = 1;
k *= (k + 9);
console.log(k);
2. Get ready to perform the action to trigger your client script. For example, if your client script trigger
(entry point) is saveRecord on the Purchase Order record, open a new purchase order in NetSuite,
enter your data, but do not click Save.
3. Access the debugger in your browser (before triggering the script):
■ Enter CTRL+SHIFT+I in Chrome
■ Enter CTRL+SHIFT+I in Firefox
■ Enter CTRL+OPTION+I in Safari
Note: If you access the browser debugger before you are ready to trigger your script, the
debugger may pause at every action you perform in the browser causing unnecessary and
premature interaction with the debugger.
4. When the debugger is open, click Save on the purchase order (in this example). The debugger will
pause the execution of your script at the location of the ‘ debugger;‘ statement. You can now use
the debugger tools in your browser to step through the code, look at values, set breakpoints, etc.
Refer to the documentation for your browser for more information.
When debugging client scripts, some scripts might be minified. Minified scripts have all
unnecessary characters removed, including white space and new line characters. You can use
your browser debug tools to de-minify the script. This is typically done using the { } button. See the
documentation for your browser for more information.
5. When you are done using the debugger, it can be closed. Your NetSuite page will remain displayed
and you can continue using NetSuite.
For additional information about working with client scripts, see the help topics SuiteScript 2.x Client
Script Entry Points and API and Record-Level and Form-Level Script Deployments.
Debugging a RESTlet
Applies to: SuiteScript 1.0 | SuiteScript 2.x | SuiteCloud Developer
You can use the NetSuite Debugger to debug RESTlet code in the same manner that you debug other
types of SuiteScript code.
If you have installed and set up the SuiteCloud IDE, a debug client is available for your use. The RESTlet/
Suitelet Debug Client enables you to debug deployed RESTlet and Suitelet SuiteScripts with the
SuiteCloud IDE Debugger. The client is only accessible after a debug session is started. For information
about SuiteCloud IDE, see SuiteCloud IDE Plug-in for Eclipse Guide.
Note: In addition to debugging RESTlet script code, you should test the HTTP request to be
sent to the RESTlet. Free tools are available for this purpose, such as Send HTTP Tool (https://
www.softpedia.com/get/Internet/Servers/Server-Tools/WIN-HTTP-Sender.shtml).
1. Before you deploy a RESTlet to be debugged, ensure that the script does not include the HTTP
authorization header, as this header can prevent the debugger from working.
2. Ensure that on the script deployment record, the Status value is set to Testing.
3. Go to Customization > Scripting > Script Debugger.
4. Click the Debug Existing button in the main Script Debugger page.
Note: This button only appears when you have deployed scripts with the status is set to
Testing.
5. Select the RESTlet script that you want to debug in the Script Debugger popup.
After you click the Select option button, the RESTlet's cookies display in a banner.
6. Copy the cookies and paste them into a text file so that you have them available.
7. Click the Select and Close button in the Script Debugger popup.
The main Script Debugger page displays a message that it is waiting for user action.
8. Set the cookies in your client application to the values you copied in step 6, and send the RESTlet
request.
The main Script Debugger page displays the script execution as pending at the NetSuite function
restletwrapper(request).
9. With the script loaded into the Debugger, you can now step through each line to inspect local
variables and object properties. You can also add watches, evaluate expressions, and set break
points. See Script Debugger Interface for information about stepping into/out of functions, adding
watches, setting and removing break points, and evaluating expressions.
The Script Debugger adheres to the following metering and permission restrictions for all SuiteScript 1.0,
SuiteScript 2.0, and SuiteScript 2.1 script types:
■ A user is only allowed to debug one script at a time. Attempting to debug multiple scripts
simultaneously (for example, by opening two different browser windows) will result in the same script/
debugging session appearing in both windows.
■ Users can debug only their own scripts in their current login session.
■ There is a 1000 unit usage limit on all scripts being debugged. This is important to note, particularly
for script types such as scheduled scripts, which are permitted 10,000 units when running in NetSuite.
If, for example, you load a 2,000 unit scheduled script into the Debugger and attempt to step through
or execute your code, the Debugger will throw a usage limit error when it reaches 1000 units.
■ Email error notification is disabled for scripts being debugged.
■ Execution log details are displayed on the Execution Log subtab in the Debugger rather than in the
execution log on the Script Deployment page for all SuiteScript 1.0 and SuiteScript 2.0 scripts. For
SuiteScript 2.1 scripts, execution log details are displayed on the Console tab of the Chrome DevTools
debugging window.
Also refer to the SuiteScript Governance and Limits help topic for governance limits on script types and
API modules.
Idle Timeouts
The SuiteScript Debugger and the 2.1 Script Debugger for all script types have idle timeouts. Your debug
session will end if you stop interacting with the debugger, or if you have exceeded the maximum allowed
amount for a debug session.
■ You have exceeded the maximum allowable idle time for debugging scripts. To debug another script,
reload the script debugger page and start a new debugging session.
If you receive this message and you are debugging a deployed SuiteScript 1.0 or SuiteScript 2.0 script,
click Go Back. You must then reload your script by clicking Debug Existing.
If you are debugging a SuiteScript 1.0 or SuiteScript 2.0 script in on-demand mode, click Go Back, click
in the Debugger text area, and re-type (or copy and paste) your code snippet. See Debugging SuiteScript
1.0 and SuiteScript 2.0 Scripts for information about deployed and on-demand debugging modes for
SuiteScript 1.0 and SuiteScript 2.0 scripts.
There is also a ten–minute global timeout on all scripts being debugged. This means that even if you are
performing user actions within the Debugger every two minutes, the Debugger will still timeout after ten
minutes.
SuiteScript 2.1
A timeout can occur in two ways when using the 2.1 Script Debugger:
■ There has been no user action within the debugger for 5-minutes (300 seconds). If you do not perform
some user action in the debugger within five minutes, Chrome DevTools will disconnect and you will
see this message:
Clicking Reconnect DevTools does not resume your debug session. You must return to the Script
Debugger tab and click the X button. Then click Switch To Editor and click Debug Script to start a
new debug session. If you leave the Chrome DevTools tab open, it will be used for the new debugging
session. If you close the Chrome DevTools tab, a new one will open when you start a new debugging
session.
■ You have reached the overall time limit for a debugger session. You set this time limit using the
IDLE_SESSION_TIMEOUT_IN_MINUTES general preference, which sets the maximum time for a
2.1 Script Debugger session, regardless of whether there is user action or not. You can set the
IDLE_SESSION_TIMEOUT_IN_MINUTES by going to Setup > General Preferences. Although you can
enter a value larger than 20 minutes, a 2.1 Script Debugger session is limited to a maximum of 20
minutes. Note that this preference also sets the timeout for a NetSuite user session (see the help topic
Setting General Account Preferences).
There are several errors thrown when a 2.1 Script Debugger timeout occurs:
■ An error message “You have exceeded the maximum allowable idle time for debugging scripts. To
debug another script, reload the script debugger page and start a new debugging session” will be
thrown.
■ DEBUGGER_SESSION_TIMEOUT error will be thrown if the timeout occurred based on the
IDLE_SESSION_TIMEOUT_IN_MINUTES general preference value.
■ DEBUGGER_IDLE_TIMEOUT error will be thrown if there has been no user action for five minutes.
If any of these timeouts occur, you can return to the Script Debugger page and click the X button to stop
debugging. You can then click Switch to Editor to reload the script and start a new debugging session.
SuiteCloud Processors
Applies to: SuiteScript 2.x | SuiteCloud Developer
SuiteCloud Processors is the current system used to process scheduled scripts and map/reduce scripts.
Before SuiteCloud Processors was introduced, scheduled scripts and map/reduce scripts were exclusively
processed by scheduling queues. All scheduled script and map/reduce script jobs submitted to the same
queue were processed on a FIFO (first in, first out) basis, based on the queue submission time stamp.
This system had several limitations. The scheduling queues didn't provide automated load balancing or
a way to prioritize specific jobs. Users with access to multiple queues (accounts with SuiteCloud Plus)
were forced to manually determine the optimal configuration of jobs to queues. For the jobs that needed
to be processed in a certain order, this method was useful but it created unintended dependencies
among many of the jobs submitted. Any delay in processing one job would create a bottleneck resulting
in several jobs waiting in one queue when other queues were underutilized or not utilized at all.
SuiteCloud Processors resolves many of those limitations. A scheduler now automatically determines
the order in which jobs start to process. The scheduler uses algorithms that are based on user-defined
priority levels, submission time, and user-defined preferences. The result is increased throughput,
reduced wait times, and the elimination of most bottlenecks. In addition, SuiteCloud Processors requires
less user intervention and enables scheduled scripts and map/reduce scripts to start sooner.
Note: Some features of SuiteCloud Processors are available only to accounts that have one or
more SuiteCloud Plus licenses. For more information about SuiteCloud Plus, see the help topic
SuiteCloud Plus Settings.
To understand how SuiteCloud Processors work, familiarize yourself with these key terms.
Term Definition
Job A piece of work submitted to SuiteCloud Processors for processing. Each job is executed by a single
processor.
Term Definition
Priority Priority of a job. The priority of submitted jobs determines the order in which the scheduler sends
the jobs to the processor pool. Priorities are set on the deployment record or from the SuiteCloud
Processors Priority Settings Page.
Processor A virtual unit of processing power that executes a job. It is not distinguished as an individual physical
entity, but as a single processing thread.
Processor Represents the number of processors available to a specific account. For accounts without
Pool SuiteCloud Plus, the processor pool contains two processors. For more information, see Accounts
Without a SuiteCloud Plus License.
For accounts with SuiteCloud Plus, the processor pool contains at least two and up to 60 processors
depending on the number of SuiteCloud Plus licenses the account has. For more information, see
the help topic SuiteCloud Plus Settings.
Queue With SuiteCloud Processors, a queue is no longer a separate processing mechanism. On scheduled
script deployments, the Queue field remains to accommodate deployments that rely on the FIFO
(first in, first out) order imposed by an individual queue. However, all jobs that use queues are
processed by the same processor pool that handles the jobs without queues. All jobs compete using
the same common processing algorithm.
Scheduler The scheduler determines the order in which jobs are sent to the processor pool. The scheduler
uses algorithms that are based on user-defined priority levels, submission time, and user-defined
preferences.
Task A script instance that is submitted for processing. Each task is handled by one or more jobs.
SuiteCloud Processors currently supports the processing of scheduled scripts and map/reduce scripts.
You can submite these scripts in several ways:
■ You can set a one-time or recurring submission schedule from the script deployment record UI.
■ You can select Save and Execute from the script deployment record UI to submit an on-demand
instance of the script.
■ You can use a SuiteScript API to submit a script on demand.
Each submitted script instance is called a "task". Each submitted scheduled script task is handled by one
job. Each submitted map/reduce script task is handled by multiple jobs: one each for the getInput, shuffle,
and summarize stages; and a minimum of one each for the map and reduce stages. Submitted jobs are
sent by the scheduler to the processor pool.
The scheduler sends the jobs to the processor pool in a specific order. This order is determined by
priority and the order of submission. Jobs with higher priority are sent before jobs with lower priority. Jobs
with the same priority are sent to the processor pool in the order of submission. For more information
about priorities and examples of scheduling based on priorities, and to understand how scheduled
scripts and map/reduce scripts are processed differently, see SuiteCloud Processors Priority Levels and
SuiteCloud Processors Priority Scheduling Examples.
SuiteCloud Processors includes advanced settings for priority elevation and processor reservation
which can also impact the order in which jobs are sent to the processor pool. For more information, see
SuiteCloud Processors Priority Elevation and Processor Reservation (Advanced Settings).
Important: The role used to submit scheduled script tasks and map/reduce script tasks for
processing must have the following permissions:
For more information about access levels for permissions, see the help topic Access Levels for
Permissions.
For more information about submitting a script with the deployment record, see the following topics:
For more information about submitting a script with a SuiteScript API, see the following topics:
■ task.ScheduledScriptTask
■ task.MapReduceScriptTask
SuiteCloud Processors currently supports processing for two script type tasks:
For accounts with SuiteCloud Plus, the Queues multi-select field is replaced with the Concurrency Limit
field. Instead of designating a specific queue, you set the maximum number of processors available to the
deployment. This value equals the number of jobs submitted for the map and reduce stages.
For map/reduce deployments created prior to the introduction of SuiteCloud Processors, the
Concurrency Limit value is set by default. The default value is equal to the value set on the Queues
field. If Queues was previously set to 1, 3, 7, and 9, then Concurrency Limit is set to 4. If Select All was
previously enabled, then Concurrency Limit is set to empty (the number of jobs initially created for the
map and reduce stages is equivalent to the total number of processors in the processor pool).
For additional information, see the help topic SuiteScript 2.x Map/Reduce Script Type.
For all scheduled script deployments created after the introduction of SuiteCloud Processors, the Queue
field is removed. These deployments can't use queues.
For all scheduled script deployments created prior to the introduction of SuiteCloud Processors, the
Queue field remains by default. This applies to accounts with and without SuiteCloud Plus. You have
control over whether to stop using queues. The deployment record includes a Remove Queue option.
Once you select this option, the deployment no longer uses a queue and cannot revert back to using a
queue.
The Queue field remains to accommodate deployments that rely on the FIFO order of processing
imposed by an individual queue. However, all jobs that use queues are processed by the same processor
pool that handles the jobs that do not use queues. All jobs compete with each other using the same
common processing algorithm.
Note: For deployments that continue to use queues, all jobs assigned to the same queue should
have the same priority. In most cases, you can keep the default (standard) priority of these jobs.
However, in some cases, you may want to change these jobs to a higher or lower priority. One
scenario is if you want to ensure that a specific queue always has a processor available. In that
case, designate the jobs assigned to that queue as high priority. Alternatively, if you have a group
of lower priority jobs, you can designate them as low priority and assign them to the same queue.
That will ensure that only one is processed at a time.
Important: SuiteCloud Processors are used to execute (process) all scheduled script and map/
reduce script instances. This topic does not apply to scheduled script deployments that continue
to use queues. See the help topic SuiteCloud Plus Settings for more information.
Standard 1 5
Premium 3 15
Enterprise 6 30
Ultimate 12 60
*The default number of SuiteCloud Processors available is 2 if you have not purchased any SuiteCloud
Plus licenses.
For more information, see the help topics SuiteCloud Plus Settings and NetSuite Service Tiers.
If any of your scripts depend on implicit dependencies imposed by having one processor, you may
be required to update your existing scripts for this feature. When an account has access to only one
processor, jobs are processed one at a time. If all jobs have the same priority, the order of processing is
always first in, first out (FIFO). Some scripts may depend on this behavior. With the addition of an extra
processor, these scripts may no longer process in the correct order.
For example, if you have a script that preprocesses data for a second script, the first script must complete
execution before the second script begins. With one processor, you can submit the scripts in the
appropriate order and know that the order of processing is as expected. With two processors, the second
script submitted might start execution before the first script completes.
1. Check your scheduled and map/reduce scripts for ones that depend on a specific order of
execution.
2. Use the following SuiteScript APIs in the first script to programmatically submit the dependent
script. This ensures that the scripts are always executed in the correct order.
■ For a scheduled script, call task.ScheduledScriptTask and place the code at the end of the
script.
■ For a map/reduce script, call task.MapReduceScriptTask and place the code at the end of the
summarize stage.
SuiteCloud Processors consider submission time and priority level when processing scripts. This means
that higher priority jobs are sent to the processor pool first. Lower priority jobs are sent to the processor
pool after all higher priority jobs are sent. The scheduler sends jobs with the same priority to the
processor pool in the order of they're submitted.
■ High: Use this priority level to mark critical jobs that require more immediate processing. The
scheduler sends these jobs to the processor pool first.
■ Standard: This is the default setting and is a medium priority level. The scheduler sends these jobs to
the processor pool if there are no high priority jobs waiting.
■ Low: Use this priority level to mark jobs that can tolerate a longer wait time. The scheduler sends these
jobs to the processor pool if there are no high or standard priority jobs waiting.
For example, if jobs 1 and 4 are high priority, jobs 2 and 5 are standard priority, and job 3 is low priority,
the scheduler sends the jobs to the processor pool in this order:
■ Job 1
■ Job 4
■ Job 2
■ Job 5
■ Job 3
By default, all jobs have a standard priority, but you can change the priority on the deployment record or
on the SuiteCloud Processors Priority Settings Page. For examples that demonstrate how changing the
priority can change the order of processing, see SuiteCloud Processors Priority Scheduling Examples.
The Priority Settings page lists each scheduled script deployment and map/reduce script deployment in
your account. Each line item corresponds to one deployment record. To access the Priority Settings page,
go to Customization > Scripting > Priority Settings.
The Priority Settings page lets you manage the SuiteCloud Processors Priority Levels for multiple
deployments at one time. You can also use this page to remove queues for scheduled script deployments.
To save changes made to the page, such as changing priorities, use the Submit button. To reset priorities
for all listed scripts to the Standard priority, use the Reset Priorities button.
The Priority Settings page lists priority settings for scripts that include the following columns:
Column Description
Internal ID The internal ID for the script deployment record, as shown on the Script Deployments list page
(for example, 345).
Edit | View Links to the edit and view modes of the deployment record.
Script Corresponds to the Name field value on the script record associated with the deployment
record.
Status Indicates how and when a script can be submitted for processing. This value is set with the
Status field on the deployment record. Possible values are:
■ Testing: Indicates that you can test the script in the SuiteScript Debugger. The script
deployment can be submitted for processing by the script owner only.
■ Scheduled: Indicates that you can schedule a single or recurring instance of the script on the
deployment record. You cannot submit an on demand instance of the script when it has this
status.
■ Not Scheduled: Indicates that you can submit an on demand instance of the script with the
Save and Execute button or a SuiteScript API. You can submit an on demand instance of the
script only if there is no other unfinished instance of the same script.
Remove Queue Applies only to scheduled script deployments. Check this box to remove queues from an existing
scheduled script deployment. You can remove queues for multiple deployments at one time with
this column. Queues aren't shown as removed until you submit the page.
Type Indicates whether the deployment is for a scheduled script or map/reduce script.
Queue Applies only to scheduled script deployments. Shows a value if the deployment is still using
queues. After you remove queues, this value is empty.
Column Description
Concurrency Limit Applies only to map/reduce script deployments on accounts that use SuiteCloud Plus. The
maximum number of processors available to a map/reduce script deployment. You set this value
on the map/reduce deployment record.
Priority The priority setting for the deployment. For additional information, see SuiteCloud Processors
Priority Levels.
The examples in this section, Default Priority Scheduling Example and Varying Priority Scheduling
Example, show three diagrams. The diagrams compare how 18 jobs as they are handled by:
This table shows the duration of each job submitted. As the examples show, the processing environment
doesn't affect the time it takes to complete each job after processing starts.
Note: Each map/reduce stage is handled by a minimum of one job. Therefore, the duration listed
for map/reduce jobs is per stage. For example, the reduce stage jobs 11 and 12 have a combined
duration of 5. This means that the sum of the duration of jobs 11 and 12 is 5. When one of the
jobs is canceled or not created, the combined duration becomes the duration of the remaining job
from the pair.
Job Duration
1 5
2 2
3 2
4 6
5 +6 2
7 +8 1
9 +10 5
11 +12 5
13 +14 2
15 3
16 3
17 3
18 2
The map/reduce deployment in the first diagram has a Queues value of 2 and 3. The map/reduce
deployment in the second and third diagrams has a Concurrency Limit value of 2.
Note: With the introduction of SuiteCloud Processors, the Queues field is replaced with the
Concurrency Limit field on map/reduce deployments.
Diagram Key
■ The black circles are scheduled script jobs. Each scheduled script is processed by a single job.
■ The red circles are map/reduce jobs. In this example, all of the map/reduce jobs belong to a single
map/reduce task. The map/reduce jobs include a label that indicates the map/reduce stage being
processed.
■ The jobs in columns labeled Q1, Q2, and Q3 are for deployments that still use queues. The jobs in
columns without a label are for deployments that no longer use queues.
■ P1, P2, and P3 represent the processors that are available in the processor pool.
Note: Although processors are labeled for this example, they are not technically individual
entities. Also, a real account would never have only three processors available to it. The
minimum number of processors available to an account with SuiteCloud Plus is listed at
SuiteCloud Plus Settings.
■ The numbers within each circle represent the time stamp on the job submission, with 1 being the first
job submitted. The example also uses this number as a unique identifier for each job.
■ Arrows represent dependencies. For example, in the Scheduling Queues diagram, job 2 cannot start
until job 1 is complete.
□ Black arrows represent queue dependencies. Jobs within a queue must be processed in the order
they were submitted.
□ Red arrows represent dependencies imposed by the map/reduce algorithm.
□ Green arrows indicate access to processors.
Scheduling Queues Only SuiteCloud Processors – All Queues SuiteCloud Processors – Some
Removed Queues Removed
Time Scheduling Queues Only SuiteCloud Processors – All Queues SuiteCloud Processors – Some
Slot Removed Queues Removed
101 Jobs 1, 4, and 6 start. Jobs 1, 2, and 3 start. Jobs 1, 4, and 5 start.
103 Job 6 completes. Jobs 2 and 3 complete. Job 5 completes. There is no job
6 with SuiteCloud Processors.
The next job in Q3, job 8, Jobs 4 and 5 start. In the Scheduling Queues
starts. example, jobs 5 and 6 are both
getInputstage jobs. The getInput
stage cannot be processed by
multiple jobs. Since this map/
reduce deployment is not using
queues, multiple getInput stage
jobs are no longer needed.
Job 7 starts.
Time Scheduling Queues Only SuiteCloud Processors – All Queues SuiteCloud Processors – Some
Slot Removed Queues Removed
stage. Job 7 is no longer
needed, so it is canceled.
Job 7 starts.
106 Job 1 completes. Job 7 completes. Since job 7 completes Job 1 completes.
the entire map stage, job 8 is no longer
The next job in Q1, job 2, needed. Job 8 is canceled. The next job in Q1, job 2, starts.
starts.
Job 1 completes.
Q2 is blocked. The next job in The first job in Q3, Job 15, starts.
Q2, job 11, cannot start. It is
dependent on job 10, and job
10 is not complete.
The next job in Q1, job 3, The next job in Q1, job 3, starts.
starts.
109 Job 10 completes. Jobs 4 and 15 complete. Job 9 completes. There is no job
10 with SuiteCloud Processors. In
Job 11 can now start and Q2 Jobs 16 and 17 start. the Scheduling Queues example,
is no longer blocked. The jobs 9 and 10 are both shuffle
next job in Q3, job 12, starts. stage jobs. The shuffle stage
These are both reduce stage cannot be processed by multiple
jobs. The reduce stage can be jobs. Since this map/reduce
processed by multiple jobs. deployment is not using queues,
multiple shuffle stage jobs are no
longer needed.
Job 11 starts.
Time Scheduling Queues Only SuiteCloud Processors – All Queues SuiteCloud Processors – Some
Slot Removed Queues Removed
The next job in Q1, job 16, There are no additional jobs to
starts. process in Q1.
Job 13 can now start and Q2 Jobs 12 and 18 start. Jobs 13 and 17 start.
is no longer blocked. The
next job in Q3, job 14, can
also start. But these are both
summarize stage jobs, and the
summarize stage cannot be
processed by multiple jobs.
Job 13 starts first, so job 14 is
canceled.
The next job in Q1, job 17, The next job in Q3, Job 18, starts.
starts.
114 Job 13 completes. Jobs 11, 12, and 18 complete. Job 13 completes. There is no job
14 with SuiteCloud Processors.
There are no additional jobs to Job 13 starts In the Scheduling Queues
process in Q2. example, jobs 13 and 14 are
both summarize stage jobs. The
summarize stage cannot be
processed by multiple jobs. Since
this map/reduce deployment
is not using queues, multiple
summarize stage jobs are no
longer needed.
The next job in Q3, job 18, There are no additional jobs to
starts. process.
The map/reduce deployment in the first diagram has a Queues value of 2 and 3. The map/reduce
deployment in the second and third diagrams has a Concurrency Limit value of 2.
Note: With the introduction of SuiteCloud Processors, the Queues field is replaced with the
Concurrency Limit field on map/reduce deployments.
The second and third diagrams vary from Default Priority Scheduling Example as follows:
■ In the second diagram, jobs 15 and 18 are high priority. Job 4 is low priority. The remaining jobs are
standard priority.
■ In the third diagram, job 4 is low priority. Jobs 15 and 18 in the third diagram are standard priority.
Diagram Key
■ The black circles are scheduled script jobs. Each scheduled script is processed by a single job.
■ The red circles are map/reduce jobs. In this example, all of the map/reduce jobs belong to a single
map/reduce task. The map/reduce jobs include a label that indicates the map/reduce stage being
processed.
■ The circles with blue fill are high priority. The circles with gray fill are low priority. The circles
with white fill are standard priority.
■ The jobs in columns labeled Q1, Q2, and Q3 are for deployments that still use queues. The jobs in
columns without a label are for deployments that no longer use queues.
■ P1, P2, and P3 represent the processors that are available in the processor pool.
Note: The processors are labeled for this example. Although technically, processors are not
distinguished as individual entities. Also, a real account would never have only three processors
available to it. The minimum number of processors available to an account with SuiteCloud Plus
is listed at SuiteCloud Plus Settings.
■ The numbers within each circle represent the time stamp on the job submission, with 1 being the first
job submitted. The example also uses this number as a unique identifier for each job.
■ Arrows represent dependencies. For example, in the Scheduling Queues diagram, job 2 cannot start
until job 1 is complete.
□ Black arrows represent queue dependencies. Jobs within a queue must be processed in the order
they were submitted.
□ Red arrows represent dependencies imposed by the map/reduce algorithm.
□ Green arrows indicate access to processors.
Scheduling Queues Only SuiteCloud Processors – All Queues SuiteCloud Processors – Some
Removed Queues Removed
Time Scheduling Queues Only SuiteCloud Processors – All SuiteCloud Processors – Some
Slot Queues Removed Queues Removed
101 Jobs 1, 4, and 6 start. Jobs 15, 18, and 1 start. Jobs 15 and Jobs 1, 5, and 15 start. Job 4 is
18 are designated as high priority designated low priority, so it is
so they are assigned to processors processed after all other available
first (in the order of submission). standard priority jobs. All other
Job 1 is the first standard priority standard priority jobs submitted
job submitted so it is the next job before job 15 have dependencies
assigned to a processer. that are blocking them.
Job 7 starts.
104 Job 8 completes. The map Job 15 completes. Jobs 7 and 15 complete. Since job
stage can be processed by 7 completes the entire map stage,
multiple jobs. But since the Job 3 starts. job 8 is no longer needed. Job 8 is
other map stage job, job 7, is canceled.
Time Scheduling Queues Only SuiteCloud Processors – All SuiteCloud Processors – Some
Slot Queues Removed Queues Removed
unable to start (the job utilizing Jobs 9 and 16 start.
its processor, job 4, is not yet
complete), job 8 completes the
entire map stage. Job 7 is no
longer needed, so it is canceled.
The next job in Q1, job 2, starts. Jobs 16 and 17 start. The next job in Q1, job 2, starts.
Job 7 starts.
Job 9 starts.
109 Job 10 completes. Jobs 16 and 17 complete. Job 9 completes. There is no job
10 with SuiteCloud Processors. In
Job 11 can now start and Q2 Job 4 starts. Job 4 is designated as the Scheduling Queues example,
is no longer blocked. The next low priority, but all the remaining jobs 9 and 10 are both shuffle stage
job in Q3, job 12, starts. These standard priority jobs are jobs. The shuffle stage cannot be
are both reduce stage jobs. The dependent on job 9. processed by multiple jobs. Since
reduce stage can be processed this map/reduce deployment is not
by multiple jobs. using queues, multiple shuffle stage
jobs are no longer needed.
Job 11 starts.
The next job in Q1, job 16, There are no additional jobs to
starts. process in Q1.
Time Scheduling Queues Only SuiteCloud Processors – All SuiteCloud Processors – Some
Slot Queues Removed Queues Removed
dependent on job 12, and job
12 is not complete.
Time Scheduling Queues Only SuiteCloud Processors – All SuiteCloud Processors – Some
Slot Queues Removed Queues Removed
deployment is not using queues,
multiple summarize stage jobs are
no longer needed.
Priority Elevation
Priority elevation lets you to automatically increase the priority of each low or standard priority job after
a specific amount of time. The time interval starts when the job is submitted. You usually don't need to
use these settings. Because of this, priority elevation is disabled by default. However, you may need to use
them if lower priority jobs experience excessive wait times.
Note: Priority elevation only affects lower priority jobs with a wait time greater than the time
interval indicated. If a lower priority job is sent to the processor pool before the time interval ends,
it is processed with its original priority.
To access the priority elevation settings, go to Setup > Preferences > SuiteCloud Processors.
The Time Interval field shows the time interval set for priority elevation. When you select Custom
Priority Elevation, you can edit the field. Otherwise, the field shows a value that corresponds to the
option selected, but you can't edit it..
Note: Click Advanced at the top of the page to access Custom Priority Elevation and Time
Interval.
Processor Reservation
Processor reservation lets you to reserve processors for high priority jobs. You usually don't need to use
these settings. Because of this, processor reservation is disabled by default.
To access the priority reservation settings, go to Setup > Preferences > SuiteCloud Processors. Click
Advanced at the top of the page.
When you select Enable Reservation, you can reserve all but one of your available processors from
the Number of Processors Reserved dropdown list. If a high priority job is submitted, it's sent to the
processor pool if there's at least one processor available. If a standard or low priority job is submitted,
it's sent to the processor pool only if there are more processors available than the number reserved. For
example, let's say you have 10 processors reserved out of 25 total processors. A standard or low priority
job is sent to the processor pool if there are at least 11 processors available. If there are 10 processors or
fewer available, the lower priority job has to wait.
Important: Changes to the Number of Processors Reserved apply to all jobs that haven't yet
started. This can have immediate affect map/reduce scripts, since each stage is processed by at
least one job. If a high priority map/reduce script task is executing and you change the setting, the
new value applies to all jobs for the tasks that haven't started yet. This includes jobs created from
yielding.
Processor reservation reduces the number of processors available for standard and low priority jobs.
As a result, it can reduce the throughput of these jobs. The Reuse Idle Processors setting temporarily
releases reserved processors that have not been used in the past 24 hours. This increases the number of
processors available for lower priority jobs.
When Reuse Idle Processors is enabled, it initiates an hourly recurring audit. The system uses the data
collected to determine whether to release reserved processors. After reserved processors are released,
the audit data is used to determine whether the system needs to increase reserved processors.
Important: If the system decreases or increases the number of reserved processors, additional
decreases are not made for 24 hours. However, additional increases (up to the selected limit) can
still be made after each hourly audit. This process continues if Reuse Idle Processors is enabled.
The system analyzes the following data points during this process:
If Then
c is less than a The number of processors available to lower priority jobs is increased by a – c
(up to the value of a).
This means that some reserved
processors were not used.
e is less than b AND d is more than The number of reserved processors is increased by d (up to the value of b)
0
The system cannot increase the number of reserved processors over the limit
set for Number of Processors Reserved. In other words, e cannot be greater
than b.
SuiteScript execution can be monitored and audited using script logs. You can view Script execution
details on the Script page, the Script Deployment page, and in the SuiteScript Debugger. You can also
view a list of all records that have a user event script or a client script associated with a record on the
Scripted Record page. And, you can also set runtime options to specify when a script is executed. The
Application Performance Management (APM) SuiteApp can be used to view and manage the performance
of NetSuite customizations and business critical operations. For more information, see the following help
topics:
Script execution details are logged on the Execution Log tab included on the Script page, Script
Deployment page, and on the SuiteScript Debugger. You can search and customize the logs to find what
you need.
The Execution Log tab displays all dates and times in the local time zone set in the user preferences.
Important: When you're using the SuiteScript Debugger to debug a script, all logging details
appear on the Execution Log tab in the Debugger. You'll need to deploy the script first to see
logging details on the Script Deployment page's Execution Log tab.
The following figure shows two types of execution log messages for a Suitelet.
The first message is an unexpected error that is generated because a Suitelet script called an undefined
method. The second message is user-generated by the following line(s) in this Suitelet code using the
SuiteScript 2.x N/log Module:
By default, the Execution Log tab shows the Default Script Notes View. This default view shows all log
types from the current day's script executions.
To view script executions for days other than the current day, click the Customize View button. Specify
search criteria such as script execution dates, details, names, and script types, and then name your
custom view in the Search Title field, as shown here:
The following figure shows a customized view of the execution log. The new view type has been selected
from the View list. This view shows log details for days other than the current day.
For more information about viewing script execution logs, see Viewing a List of Script Execution Logs.
Important: The capacity for script execution logs on the Execution Log tab is shared by
customers on the same database. For further protection against excessive logging, script
execution logs are governed by a total storage limit on each instance of the NetSuite database.
On each NetSuite server, if the database table that stores logs reaches this limit, all logs (across
all customers on that server) are purged. This means that you may have logs up to 30 days if the
volume is low, but you may have logs of less than a week if the log volume is extremely large. Use
the Script Execution Log page for logs up to 30 days, regardless of volume. For more information
about governance of script logs, see Governance on Script Logging.
The Script Execution Log page shows log details across all scripts for 30 days. You can access the Script
Execution Log page by going to Customization > Scripting > Script Execution Logs.
This page displays all dates and times in your local time zone set in the user preferences.
■ Search for specific logs using filter options, such as log level, execution date range, and script name.
You can view other logs by using filter options.
■ Download the list as a CSV file or an Excel spreadsheet. Downloads may be limited to 10,000 entries.
■ Print the log list.
Note: These logs will not be moved with your NetSuite account to the new data center built on
Oracle Cloud Infrastructure (OCI). For the first 29 days after the move, the displayed values will be
calculated using data stored since the date of the move, rather than from the last 30 days.
The following figure shows a script execution log list filtered to show scripts that violated the web services
and RESTlet account concurrency governance.
You can view a list of all records that have a user event script or a client script associated with a record on
the Scripted Records page. By default, the list only shows records with at least one script attached.
Tip: To view a list of all records in your account, click the Show Undeployed box. You can also use
the Script filter list to show only records associated with specific scripts.
The Scripted Records page is helpful for troubleshooting problematic scripts and workflows. You can use
the page to:
■ specify the execution order of scripts associated with each specific record type
■ edit script deployment statuses
■ deploy or inactivate script deployments
■ change workflow statuses
■ set workflow initiation details
When determining he order of execution, scripts which are not localized takes precedence over those
who are localized. For information about Localization Context, see Localization Context.
To access the Scripted Records page, go to Customization > Scripting > Scripted Records.
Each record is shown on the Scripted Record page. To access a specific scripted record:
■ Click View to view information about the scripts associated with a record type, or
■ Click Edit to change a record’s script deployment order or to deploy or undeploy scripts for that
record type.
The Scripted Record page includes these subtabs: User Event Scripts, Client Scripts, Custom Forms,
Localized User Event Scripts, Localized Client Scripts, and Workflows (if enabled).
■ View information about the user event scripts for a record type:
□ The Script column shows the script name -click it to view the Script Deployment record. See the
help topic Script Deployment.
□ The Owner column lists the script’s owner.
□ The API Version column lists the script’s API version.
□ The From Bundle column lists the number of the bundle the script is included with. Click the
bundle number to view information about the bundle.
□ The Bundle Name column lists the name of the bundle that the script is included with. Click the
bundle name to view information about the bundle.
□ The Company Name of Bundle column lists the name of the bundle that the company uses to
identify the bundle.
□ The Status column shows the script's release status – either Testing or Released. See Setting Script
Deployment Status.
□ The Before Load Function column lists the names of the functions that are set to execute on the
beforeLoad user event entry point.
□ The Before Submit Function column lists the names of the functions that are set to execute on
the beforeSubmit user event entry point.
□ The After Submit Function column lists the names of the functions that are set to execute on the
afterSubmit user event entry point.
□ The Options column lists any options in the script and their setting.
Note: For information about user event script entry points, see the help topic SuiteScript 2.x
User Event Script Entry Points and API.
Note: Scripts execute by function order first, then by the order listed on the Scripted Records
page. You can't define individual execution sequences for beforeLoad, beforeSubmit, and
afterSubmit separately. When afterSubmit functions are executed, those with a beforeSubmit
function will always go first, and after that, the execution sequence defined by the customer will
be respected. For example, deploy four user event scripts on any record:
□ In the first script (A), define beforeLoad and afterSubmit entry points only
□ In the second script (B), define beforeLoad and beforeSubmit entry points only
□ In the third script (C), define afterSubmit entry point only
□ In the fourth script (D), define beforeSubmit and afterSubmit entry points only
The entry points will be executed in this order:
□ Script A beforeLoad
□ Script B beforeLoad
□ Script B beforeSubmit
□ Script D beforeSubmit
□ Script D afterSubmit
□ Script A afterSubmit
□ Script C afterSubmit
Notice, that the afterSubmit function of Script D is executed before the afterSubmit functions
of Script A and Script C, even if Script D is listed last in the execution order on the User Events
tab.
Note: When there is a workflow defined for the same record as a user event script, and
both include afterSubmit events, the user event script is executed in its entirety before the
workflow’s afterSubmit event.
Tip: Deploying a large number of user event scripts of the same event type can impact
performance. Avoid deploying more than 10 scripts of the same event type.
■ Rearrange the global client scripts to change their execution order – drag and drop to move a script to
the top to have it execute first.
Note: For information about client script entry points, see the help topic SuiteScript 2.x Client
Script Entry Points and API.
□ The Validate Line Function column lists the names of the functions that are set to execute on the
validateLine client script entry point.
Workflows Subtab
Use the Workflows subtab to select a workflow to:
■ Update the workflow status using the Status list -choose from Testing, Not Running, or Released.
■ Set the initiation trigger type: All, Before Record Load, Before Record Submit, After Record Submit. Use
the Trigger Type list to set the type of trigger on which the workflow is to initiate. Note that this is not
available for workflows that are locked by a bundle.
■ Check the On Create box to run the workflow when a record is created. Note that this is not available
for workflows that are locked by a bundle. See the help topic Initiating a Workflow on an Event.
■ Specify whether the workflow should initiate on view or update events by checking the On View or
Update box. Note that this is not available for workflows that are locked by a bundle. See the help
topic Initiating a Workflow on an Event.
■ View information about the workflows for a record type:
□ The Workflow column shows the workflow name -click it to view the workflow in SuiteFlow. See the
help topic Workflow Manager Interface.
□ The Internal ID column lists the workflow’s internal ID. Click the ID to view the workflow in the
SuiteFlow UI. See the help topic Workflow Manager Interface.
□ The Description column lists a description of the workflow, if available.
□ The From Bundle column lists the number of the bundle the form is included with. Click the
bundle number to view information about the bundle.
□ The Bundle Name column lists the name of the bundle that the form is included with. Click the
bundle name to view information about the bundle.
□ The Company Name of Bundle column lists the name of the bundle that the company uses to
identify the bundle.
□ The Owner column lists the workflow’s owner.
□ The Status column shows the workflow's release status -either Testing, Not Running, or Released.
See the help topic Release Status.
□ The Trigger Type column lists the client event that'll trigger the workflow: All, Before Record Load,
Before Record Submit, After Record Submit. See the help topic Client Triggers Reference.
□ The On Create column lists whether the workflow initiates on record creation events. See the help
topic Initiating a Workflow on an Event.
□ The On View or Update column lists whether the workflow initiates on record view or update
events. See the help topic Initiating a Workflow on an Event.
For information about SuiteFlow workflows, see the help topic SuiteFlow Overview. Also note that the
SuiteFlow feature must be enabled to use workflows. See the help topic Enabling SuiteFlow.
■ Rearrange the localized user event scripts to change their execution order – drag and drop to move a
script to the top.
Note: For information about user event script entry points, see the help topic SuiteScript
2.x User Event Script Entry Points and API. For information about Localization Context, see
Localization Context.
Tip: Deploying a large number of user event scripts of the same event type can impact
performance. Avoid deploying more than 10 scripts of the same event type.
■ Rearrange the localized client scripts to change their execution order – drag and drop to move a script
to the top.
■ Change a script’s deployment status from Testing to Released.
■ Deploy a script by checking the Deployed box.
■ View information about the client scripts for a record type:
□ The Script column shows the script name – click it to view the Script Deployment record. See the
help topic Script Deployment.
□ The Owner column lists the script’s owner.
Note: For information about client script entry points, see the help topic SuiteScript 2.x
Client Script Entry Points and API. For information about Localization Context, see Localization
Context.
The Application Performance Management (APM) SuiteApp helps you monitor and optimize your NetSuite
customizations and key business operations with a performance dashboard.
With APM, you get data visualizations, page time summaries, and script analysis tools to help you boost
the NetSuite UI's speed.
For additional information about APM, see the help topic Application Performance Management (APM).
If you haven't already created a Script Deployment record for your SuiteScript file, see the help topic
SuiteScript 2.x Entry Point Script Creation and Deployment.
Once you've set up your script deployment, see these help topics to learn about more deployment and
runtime options:
Also see these help topics for information related to script deployments, but not necessarily specific to
any deployment/runtime options.
■ Script Deployment
■ Methods of Deploying a Script
On the Script Deployment page, use the Event Type field to choose the event that'll trigger your script
(see following figure). If the Event Type field is left blank, the script will execute only on the events
specified in the script file.
Note: The Event Type field is available on Script Deployment pages for Suitelet, user event, and
record-level client scripts only.
Use the Event Type field to specify a script execution context at the time of script deployment, without
having to modify your .js script file. After you select an event type and click Save, the deployed script will
execute only on that event, regardless of the event types specified in the .js script file.
Note that event types selected on the Script Deployment page take precedence over the event types
specified in the .js script file. For example, if the create event type is specified in the script, selecting Edit
from the Event Type field on the Script Deployment page will restrict the script from running on any event
other than Edit.
The following snippet is from a user event script. Notice that the event type specified in the code is create
(context.UserEvent.CREATE). If the Edit event type is specified on the Script Deployment page, the script
will execute only when the specified record is edited, not created.
function followUpCallAfterSubmit(type) { // execute the logic in this script onlyif a new customer is created if (context.type !== context.UserEvent
Type.CREATE) return; // obtain a handle to the newly created customer record var customerRecord = context.newRecord; // remainder of script...... }
}
In the Log Level field on the Script Deployment page, specify which log entries you want to appear on the
Execution Log tab:
The Log Level field is essentially used as a basic filtering mechanism. Each log entry written with
N/log Module methods specifies a log level based on the specific method used: log.audit(options),
log.debug(options), log.emergency(options), log.error(options).
Select one of the following log levels from the Log Level field:
■ Debug: For scripts in testing mode. Selecting this level will show all log messages (debug, audit, error,
and emergency).
■ Audit: For scripts going into production. Selecting this level will show the events that have occurred
during the processing of the script (for example, “A request was made to an external site.”).
■ Error: For scripts going into production. Selecting this level will show only unexpected script errors.
■ Emergency: For scripts going into production. Selecting this level will show only the most critical
errors in the script log.
Important: NetSuite governs the amount of logging that can be done by a company in any 60
minute time period. For complete details, see Governance on Script Logging.
Note: The log level you specify on the Script Deployment page is independent of any error
handling within your script.
See Using the Script Execution Log Tab for details on how to further customize your view of all log entries.
The Execute as Role field provides role-based granularity in terms of the permissions and restrictions for
executing scripts. For example, if a Sales Person role is selected in the Execute as Role field (see figure
below), the script will always execute based on the permissions and restrictions assigned to the Sales
Person role, even if the role of the logged in user is different. If the logged in user’s role is Administrator,
when the script executes in this user’s account, it executes based on the record-level permissions
assigned to the Sales Person role and not that assigned to the administrator role.
The Current Role value in the Execute as Role field means that the script executes using the permissions
of the currently logged-in user (the user whose account the script is running in).
SuiteScript developers can also select from custom roles created with permissions that are specific to a
script deployment.
The Execute as Role field is available on the Script Deployment pages for these script types only:
■ Suitelet
■ User Event
■ Portlet
■ Mass Update
■ Workflow Action
Note: When a script triggers other scripts, the cascading scripts will run as the role of the initial
triggering script's role, not the role specified on the cascaded script's role.
For information about SuiteScript roles and permissions, see Setting Roles and Permissions for
SuiteScript. For information about role restrictions in client SuiteScript, see the help topic Client Script
Role Restrictions.
There may be some scripts that are required to run with administrative privilege. For example, if you have
a script that creates follow-up tasks after a sales order has been saved, and the script needs to read data
from employee records, the script will not complete execution if a user's role does not have permission
to access employee records. In this case, it may be appropriate to have Administrator selected in the
Execute as Role field.
However, setting a script to execute as Administrator should be done with caution, as this option allows
scripts to execute with privileges that the logged in user does not have. This may be appropriate for
certain scripts, but there are other cases where the script performs actions that are only appropriate for
certain roles.
Note: All bundle installation scripts need to execute as Administrator, so Administrator must be
selected in the Execute As Role field for those scripts.
Note: Often, when scripts execute without logins (see Setting Available Without Login) or in the
Web store, they tend to be implemented as an Administrator whenever any meaningful interaction
with the system is required.
You can allow Suitelet scripts to be executed without a login. Select the Available Without Login box on
the Script Deployment page give users access to the Suitelet even if they're not logged in.
Warning: Suitelets configured as available without login should not be used in integration
use cases, including SDN partner SuiteApps. Suitelets configured as available without login are a
violation of Built for NetSuite (BFN) standards.
To ensure that users without an active NetSuite session can access the Suitelet, Online Form User must
be selected in the External Roles field. All other roles that require access to the script should also be
selected in the Internal Roles and External Roles fields. Values from the Departments, Groups, Employees,
and Partners fields must be cleared.
Note: The Available Without Login box is available on the Script Deployment page for Suitelets
only. When working with Client Scripts and externally available Suitelets, the Website feature must
be enabled.
To be able to select the Online Form User role in the External Roles field, the Online Forms
feature must be enabled. To enable the feature, go to Setup > Company > Enable Features. Click
the CRM subtab, and check the Online Forms box in the Marketing section. If the role is still not
available after enabling the feature, you may need to log out and log back in to see the updated
roles list.
The following are some uses cases when you might want to make a Suitelet externally available (however,
when considering these use cases, keep in mind that using Suitelets externally without login is forbidden
in BFN):
■ Hosting one-off online forms (for example, capturing partner conference registrations).
■ Inbound partner communication (such as, listening for payment notification responses from PayPal
or Google checkout, or for generating an unsubscribe request from email campaigns page, which
requires access to account information but should not require a login or hosted website).
■ For Facebook, Google, and Yahoo mashups in which the Suitelet lives in those websites but needs to
communicate to NetSuite using POST requests.
Important: Note that the data contained within the Suitelet will be less secure when it is
allowed to be accessed (using Suitelet execution) without login.
For information about errors when using the Available Without Login URL, see the help topic Errors
Related to the Available Without Login URL.
A script’s deployment status can be set to Testing or Released. When the status is set to Testing, the script
will execute for the script owner and specified audience. When the status is set to Released, the script will
execute in the accounts of all specified audience members
To set the deployment status, select either Testing or Release from the Status field on the Script
Deployment page:
Note: The Testing and Released statuses do not apply to scheduled scripts. To learn about
scheduled script deployment statuses, see the help topic Scheduled Script Submission.
Note that when using the SuiteScript Debugger to test scripts, the script's deployment status must be set
to Testing. You cannot debug a Deployed script if the status has been set to Released. (See Debugging
Deployed SuiteScript 1.0 and SuiteScript 2.0 Server Scripts and Debugging Deployed SuiteScript 2.1
Server Scripts for more information about using the SuiteScript Debugger to test existing scripts.)
If you are working with Suitelet Script Deployment records, see the help topic Errors Related to the
Available Without Login URL,to learn how Testing status affects internally and externally available
Suitelets.
Note: A bundle installation script can't execute in target accounts if its deployment status is set
to Testing.
Note that if you do not specify any values on the Audience subtab, the script will execute only for the
script owner, even if the script deployment status is set to Released.
Note: Bundle installation scripts and scheduled scripts do not have an audience. If the
deployment status is set to Released for a bundle installation script, the script will execute
automatically in target accounts when the associated bundle is installed or updated.
If you are working with Suitelet Script Deployment records, see the help topic Errors Related to the
Available Without Login URL, to learn how Released status affects internally and externally available
Suitelets.
On the Audience subtab on the Script Deployment page, define the audience access for the script. When
the script is deployed, it will only run in the roles specified in the Audience subtab.
The Audience subtab is included on the Script Deployment page for these script types: Suitelet, portlet,
user event, global client (deployed at the record-level), RESTlet, mass update, and workflow action. You
cannot specify an audience for scheduled scripts, map/reduce scripts, or bundle installation scripts.
Note: Mass update script deployments and mass updates can both be assigned an audience.
It is the user's responsibility to make sure the two audiences are in sync. For information about
working with the mass update script type, see the help topic SuiteScript 2.x Mass Update Script
Type.
■ If you don't specify any values on the Audience subtab, the script will execute only for the script owner
even if the script deployment status is set to Released. For information about the differences between
the Released and Testing deployment statuses, see Setting Script Deployment Status.
■ If you choose both role and department options on the Audience subtab, a user must belong to one
of the selected roles AND one of the selected departments to execute the script. If you choose options
for any other combinations of types (groups, employees, and partners), a user need only belong to a
selected option of one type OR of another.
■ If you want the script to run only for specific users, select the appropriate roles, departments, groups,
employees, or partners. If you want the script to run for all NetSuite users, do the following:
□ Check the Select All box beside the Internal Roles field
□ Select all roles in the External Roles field
Note: When giving access to multiple roles, particularly external roles, ensure that each
selected role has a valid need to access the script.
Be sure to save the Script Deployment record after all audience members have been defined.
If you are working with Suitelet Script Deployment records, see the help topic Errors Related to the
Available Without Login URL, which discusses the relevance of the Select All box as it pertains to internally
and externally available Suitelets.
For example, if you have a script that you want to execute for everyone in the Support Management
role, you can log into NetSuite and then switch to the Support Management role to test the script. If the
deployment status for the script is set to Testing, the script will run only for the script owner. After you
have determined that the script runs as expected for the Support Management role, you can change the
script's deployment status to Released. After it is set to Released, it will execute in the account for all those
assigned to the Support Management role.
This is a good approach for script owners to verify that their script will run in the accounts for specified
roles, departments, groups, employees, or partners.
If the currently logged user is a member of a subsidiary which is selected in the multiselect field on the
Script Deployment page, then the script is executed.
Script owners working in a OneWorld account that has multiple subsidiaries can select the subsidiaries
they want their script to run in, and then log into an account of one of the specified subsidiaries. When
a script's deployment status is set to Testing, the script will execute for the script owner and specified
audience. This is a good way for script owners to verify that the script will run in accounts for specified
subsidiaries.
In a script deployment record, the Context Filtering tab lets you specify the contexts in which a script will
run. You can use context filtering to ensure that a script runs only when necessary, which can improve
performance.
You can specify the execution context and localization context for a script:
■ Execution Context
■ Localization Context
You can use the N/recordContext module to get the context type for a record. For more information, see
the help topic N/recordContext Module.
Execution Context
Execution contexts provide information about how or when a client script or user event script is triggered
to execute. For example, a script can be triggered in response to an action in the NetSuite application,
or an action occurring in another context, such as a web services integration. You can use execution
context filtering to ensure that your scripts are triggered only when necessary. You can specify that a
script should execute only in certain contexts, and this filtering can improve performance in contexts
where the script is not required. For more information, see the help topic Execution Contexts.
On the Context Filtering tab of a script deployment record, you can select the contexts in which you want
your script to execute. Your script will not execute if it is triggered in a context that is not selected. By
default, all contexts are selected except for Web Application and Web Store. Often, it is not required to
trigger scripts in these contexts, so they are disabled by default to improve performance. If you want
your script to be triggered in these contexts, be sure to select them explicitly when you create your script
deployment record.
1. Define a new script deployment record or edit an existing one. For more information, see the help
topic Script Deployment.
2. In the script deployment record, click the Context Filtering tab. By default, all execution contexts
are selected except for Web Application and Web Store.
3. In the Execution Context field, select the contexts in which you want the script to execute. Cancel
the selection of contexts in which the script should not execute.
4. Click Save.
Localization Context
You can define the localization context in which a client or user event script can execute. You can enable
the script execution for specific localization contexts programmatically and in the UI.
Localization filtering allows you to execute a script based on the country of the active record or
transaction. For a list of records that support localization context, see Records that Support Localization
Context.
NetSuite automatically determines the localization context for records and transactions based on
their values for country fields such as subsidiary and tax nexus. It is important to understand this
determination before you set up localization context filtering for scripts. For more information, see the
help topic Record Localization Context.
You can specify the execution order of localized client and user event scripts. A maximum of 10 localized/
non-localized client scripts are supported. For more information, see The Scripted Records Page.
You can also search for localized scripts by using the N/query Module. For more information, see the help
topic N/query Module.
The following table shows how you can specify the localization context based on the script type.
SuiteScript 2.x Client Complete the following steps to add localization context filtering to client scripts:
Script Type
1. Use the localizationContextEnter(scriptContext) and
localizationContextExit(scriptContext) entry points in your script.
2. Define the localization context on the Context Filtering tab on the script
deployment record.
SuiteScript 2.x User Define the localization context on the Context Filtering tab on the script deployment
Event Script Type record only.
1. Define or edit your script deployment record. For more information, see the help topic Use the
Script Deployment Record.
2. Click the Context Filtering tab. All countries are selected by default.
3. Clear the Select All box.
4. Click on the arrow button beside the Localization Context field.
5. Select a country. The selected country is automatically displayed under Current Selections.
6. Click Done.
To avoid scrolling through a long list of countries, you can do any of the following:
■ The drop-down list on top of the popup window displays the pagination of the countries that are listed
alphabetically. Select the pagination based on the first letter of the country that you want to specify
and make your selection.
Advanced Intercompany Journal Entry Assembly Item BOM Contact (contact) Tax Type (taxtype)
(advintercompanyjournalentry) (assemblyitembom)
Assembly Build (assemblybuild) Description Item (descriptionitem) Customer (customer) Tax Code
(salestaxitem)
Credit Card Charge (creditcardcharge) Lot Numbered Inventory Item Prospect (prospect)
(lotnumberedinventoryitem)
Credit Card Refund (creditcardrefund) Markup Item (markupitem) Tax Group (taxgroup)
Inventory Adjustment
(inventoryadjustment)
Invoice (invoice)
Opportunity (opportunity)
Paycheck (paycheck)
Requisition (purchaserequisition)
Return Authorization
(returnauthorization)
Revenue Arrangement
(revenuearrangement)
Revenue Commitment
(revenuecommitment)
A log of outbound requests from NetSuite is available at Setup > Company > Communication > Outbound
Request List > Search. The Outbound Requests log includes all outgoing HTTPS and SFTP requests made
from your NetSuite account. Each SFTP request from SuiteScript is listed with a link to the specific script
deployment that issued the request. The ability to view this type of log is important for auditing account
activity. A review of this log can help you to identify requests that result in errors and requests that are
not as efficient as they could be.
The Outbound Requests log displays data in a default format that includes the URL, the method, the
result, and other useful details. You can modify this format by clicking Customize View. See the help topic
Customizing List Views for more information.
The following figure shows a customized view in which the order of columns has been modified:
By default, the Outbound Request List search is accessible only to users with the administrator role.
Administrators can provide access to additional users by assigning the Outbound Request permission, a
List type permission, to other roles.
Users with the appropriate permissions also can run adhoc searches and create their own saved
searches that return data on outbound requests. These capabilities are available at Setup > Company >
Communication > Outbound Request List > Search.
Outbound Requests searches are also available from these menu options:
Important: When writing SuiteScript, you must use the IDs listed in the NetSuite Help Center.
You can access IDs by viewing a NetSuite record's page source, but not all IDs in the source
code are supported in SuiteScript. If you create a script that references an unsupported or
undocumented ID, and NetSuite later changes the ID, your script may break.
Not all fields in the SuiteScript Records Browser can be set using SuiteScript. Some fields are read
only. Check the NetSuite UI to see if a field can be set. Generally, if you can set a field in the UI, you
can set it using SuiteScript. If you cannot set a field in the UI, you cannot set it using SuiteScript.
However, you can still get the field's value using SuiteScript.
The SuiteScript Records Browser provides a summary of all records, fields, sublists, search joins, search
filters, search columns, and record transformations that are supported in SuiteScript. Information about
elements is displayed as a series of tables.
The following table provides examples of objects and methods that use each type of ID:
■ You can use the Records Browser online, or you can download it. For information about downloading
the browser, see the help topic Downloading the SuiteScript Records Browser.
■ For information about governance applied to individual SuiteScript APIs, and about various SuiteScript
script types, see SuiteScript Governance and Limits.
■ Only the Records Browser for the most recent release of NetSuite is supported. Older versions may
still be accessible, but they are not supported.
■ Green highlighting indicates anything new in the current release.
Use the A-Z index at the top of the SuiteScript Records Browser to find a record or subrecord.
The left pane shows record names starting with your selected letter. The center pane shows the
details of the first record in the list.
2. In the left pane, click the name of the record you're interested in.
The center pane shows the record details.
You can also get to a subrecord page from one of its parent records. Each subrecord summary field on
a record page now includes a link to the subrecord page. For example, on the Sales Order page of the
Records Browser, the billingaddress and shippingaddress fields include links to the address subrecord
page. Click the summary link in the Type column to go to the subrecord page.
The SuiteScript Records Browser includes a record summary for each record exposed to SuiteScript. For
example, the following screenshot shows the record summary for a customer record:
■ Search Only: Indicates that the record does not support SuiteScript actions other than search actions.
■ Supports Deleted Record Search: Indicates that a record can be used as a filter for a deleted record
search. For more information, see Deleted Record Search.
For each record, the browser displays a series of tables that include the following information:
The following table describes some of the column names that these tables use:
nlapiSubmitField A boolean value indicating whether the field supports the record.submitFields(options) method,
which lets you perform inline editing. This column name comes from the SuiteScript 1.0 API for
inline editing (nlapiSubmitField). For more information, see the help topic Using Inline Editing.
Label The label for the field as shown in the user interface.
If the record is supported in SOAP web services or SuiteAnalytics Connect, you're directed to the
corresponding page in the SOAP Schema Browser or SuiteAnalytics Connect Browser. Otherwise, you're
directed to the first page of the respective browser. To compare record types support across SuiteScript,
SOAP web services, and SuiteAnalytics Connect, see .
The Records Browser includes a Deleted Record page, listed under D. This page lists the columns and
filters available for deleted record searches in SuiteScript.
Check a record's page in the Records Browser to see if it can be used as a filter for deleted record
searches. Records that can be used as filters have a Supports Deleted Record Search designation
on their pages. For information about running deleted record searches in the UI, see the help topic
Searching for Deleted Records.
The retrieval of deleted records in SOAP web services is a bit different. You can use the getDeleted
operation instead of running a search. For a complete list of supported record types for this operation,
refer to the DeletedRecordType enumeration in the coreTypes spreadsheet.
In the context of SuiteScript, script parameters are similar to custom fields; they are not considered to
be parameters that are passed between JavaScript functions. Script parameters share characteristics
with custom fields created through point-and-click customization. Script parameters are configurable by
administrators and the users of your Suite App, and are accessible programmatically through SuiteScript.
Script parameters are defined on the Parameters tab of the Script record page.
■ You want part of your script to be configurable, either through script deployment or by the users
of your SuiteApp. You do not need to create script parameters if your script is not designed to be
configurable.
■ You need to parameterize a script that was deployed multiple times. This approach makes it more
convenient to customize the behavior of the script for each deployment.
■ You want to configure a scheduled script. You're able to do this by specifying configuration
parameters as arguments to task.create(options).
■ With deployment-specific parameters, you can configure script behavior without writing code. These
parameters are useful when administrators deploy scripts that were installed as part of a bundle.
The parameters let administrators to control or modify the script without knowing anything about
the code. Deployment-specific parameters are similar to property or configuration files that some
applications use to modify behavior at runtime.
■ Script parameters let you to modify script behavior for troubleshooting without changing code, which
is often expensive and not feasible (for example, if the original script author is unavailable).
■ Script parameters provide flexibility to handle various inputs based on context. For example, consider
a situation in which one script is deployed to 50 different records, but requires slightly different
behavior for each record. You could hard-code and deploy 50 different scripts, but they may be
difficult to maintain because the code isn't configurable, code might be duplicated unnecessarily, and
changes in business requirements likely require code changes.
Use the following steps to create script parameters. If you are unsure how to create a script record, see
the help topic Creating a Script Record.
11. On the script record, click Save to save the script record.
You can use the Script.getParameter(options) method to reference script parameters that you create.
This method is included in the N/runtime module, and you can use other methods in this module to work
with scripts and script objects. For example, use runtime.getCurrentScript() to get a runtime.Script object
representing your script. For more information, see the help topic N/runtime Module.
Before you can reference script parameters in your script, you must create them using the NetSuite UI.
To learn how, see Creating Script Parameters. Remember the ID you used (or the ID that was generated
automatically for you) when creating a script parameter. Use this ID in your script to get the script
parameter's value.
The following example from a Suitelet obtains the value of a script parameter called
custscript_mycheckbox:
You cannot write to a script parameter using SuiteScript. You can read from these fields, but not write to
them. You can pass a value to a script parameter outside of the UI only when you call task.create(options)
to schedule a script.
For a complete example working with script parameters in a SuiteCloud project, see the help topic Disable
Tax Fields.
When you use script parameters, you can specify a preference type. Available preference types are
Company and User or you can choose not to set a preference.
■ Company: For Company preference, the parameter's value comes from the value set in Setup >
Company > General Preferences in the Custom Preferences tab. See the Example later in this section.
■ User: For User Preference, the parameter's value comes from the value set in Home > Set Preference
in the Custom Preferences tab. This lets end users override the company default script behavior and
set their own default value. End users can change script parameter values without modifying the script
or its deployments.
If you don't set a preference, the script parameter is considered a "deployment" script parameter by
default. In this case, you define the value of the script parameter on the Parameters tab of the Script
Deployment record.
Note that users who install a bundled script that uses preferences can override the default behavior of
the script and customize the script to their specific business needs. Setting preferences eliminates having
to manipulate the script code or the script deployment. For information about bundling scripts, see the
help topic SuiteBundler Overview.
Example
In this example, the Suitelet script includes a parameter called Check Box Required (with the internal ID
custscript_checkboxtest2 ) is set to the Company preference.
By going to Setup > Company > General Preferences in the Custom Preferences tab (see below),
administrators can set the default value of this parameter for the entire company. In this example, the
value of the Check Box Required script parameter is set to T (true; the box is checked).
When the Suitelet that contains this box is deployed, the Check Box Required script parameter will
appear checked.
If the Check Box Required parameter had been set to F (false; the box is not checked), the box would
have appeared empty on the form when the Suitelet was deployed.
Note: See Creating Script Parameters for steps on creating a script parameter. Also see
Referencing Script Parameters for information about accessing script parameter values.
■ With Update Deployments, script deployment parameters in target accounts are updated to match the
source account.
■ With Do Not Update Deployments, script deployment parameters in target accounts remain
unchanged.
Set the preference to Company or User if target account users need to change parameter values. Users
can change parameter values as needed, and these changes won't be overwritten on bundle update even
if the related bundle object preference is set to Update Deployments.
To prevent changes, set the bundle object preference to Do Not Update Deployments for parameters
without a preference.
For more information, see the help topic Bundle Object Preferences.
SuiteScript IDs
Applies to: SuiteScript 2.x | SuiteCloud Developer
IDs are used for several different things including permissions, features, names, tasks, and buttons.
The following table provides permission names and IDs associated with each NetSuite feature. You can
use the permission ID to return the permission levels that have been specified in your account by calling
User.getPermission(options) in the N/runtime Module.
The following link provides access to a Microsoft Excel worksheet listing the usage of most NetSuite
permissions: NetSuitePermissionsUsage.xls. You can use this list to understand the implications of
assigning a specific permission, or to find the permission required to provide access to a specific task or
page. For more information, see the help topic Permissions Documentation.
ADMI_AUDITLOGIN View Login Audit Trail Login Audit Trail None, Full
ADMI_BLCGA Balance Location Costing Group Group Average Costing None, Full
Accounts
ADMI_CASEFORM Online Case Form Customer Support and Service None, Full
ADMI_CASEISSUE Support Case Issue Customer Support and Service None, Full
ADMI_CASEORIGIN Support Case Origin Customer Support and Service None, Full
ADMI_CASEPRIORITY Support Case Priority Customer Support and Service None, Full
ADMI_CASERULE Support Case Territory Rule Customer Support and Service None, View,
Create, Edit,
Full
ADMI_CASESTATUS Support Case Status Customer Support and Service None, Full
ADMI_CASETERRITORY Support Case Territory Customer Support and Service None, View,
Create, Edit,
Full
ADMI_CASETYPE Support Case Type Customer Support and Service None, Full
ADMI_CUSTOMIZEDFIELDLEV Customize Field Level Help SuiteBuilder Customized Field None, View,
ELHELP Level Help Create, Edit,
Full
ADMI_DUPLICATESETUP Duplicate Detection Setup Duplicate Detection & Merge None, Full
ADMI_ESCALATIONRULE Escalation Assignment Rule Customer Support and Service None, View,
Create, Edit,
Full
ADMI_LOGIN_OAUTH2 Log in using OAuth 2.0 Access OAuth 2.0 None, Full
Tokens
ADMI_SAMLSSOSETUP Set Up SAML Single Sign-on SAML Single Sign-on None, Full
ADMI_SFASETUP Sales Force Automation Setup Sales Force Automation None, Full
ADMI_SWAPPRICES Swap Prices Between Price Levels Multiple Prices None, Full
ADMI_WEBSERVICESLOG View Web Services Logs Internal Web Services None, Full
LIST_EMPLOYEECHANGETYPE Employee Change Request Type Employee Change Requests None, View,
Create, Edit,
Full
LIST_ENTITY_DUPLICATES Duplicate Entity Management Duplicate Detection & Merge None, View,
Full
LIST_GLLINESAUDITLOG Custom GL Lines Plug-in Audit Custom GL Lines Plug-in None, View,
Log Create, Edit,
Full
LIST_GLLINESAUDITLOGSEG Custom GL Lines Plug-in Audit Custom GL Lines Plug-in None, View,
Log (Segments) Create, Edit,
Full
LIST_RECOGNITIONEVENTTYP Custom Recognition Event Type Advanced Revenue Recognition Or None, View,
E Advanced Expense Management Create, Edit,
Full
LIST_SYSTEMNOTES System Notes for Analytics and System Notes None, View
REST
TRAN_BLANKORDAPPRV Blanket Purchase Order Approval Purchasing and Receiving None, View,
Create, Edit,
Full
TRAN_PAYMENTRESULTPREVI View Payment Result Previews Credit Card Payments None, View,
EW Edit, Full,
Create
TRAN_VENDAUTHAPPRV Vendor Return Auth. Approval Vendor Return Authorizations None, View,
Create, Edit,
Full
TRAN_VENDRFQ Vendor Request For Quote Purchasing and Receiving None, View,
Create, Edit,
Full
The following table provides the internal IDs and feature names for all NetSuite features.
You can use the feature ID to see if a particular feature is enabled in your account by calling
runtime.isFeatureInEffect(options) in the N/runtime Module.
ACCOUNTING Accounting
AMORTIZATION Amortization
CLASSES Classes
DEPARTMENTS Departments
ESTIMATES Estimates
INSTALLMENTS Installments
INTRANET Intranet
INVENTORY Inventory
JOBS Projects
KUDOS Kudos
LOCATIONS Locations
MULTILANGUAGE Multi-Language
OPPORTUNITIES Opportunities
PAYABLES A/P
PAYROLL Payroll
RECEIVABLES A/R
REQUISITIONS Requisitions
REVRECVSOE VSOE
STACKABLEPROMOTIONS SuitePromotions
SUITECOMMERCE SuiteCommerce
SUITESIGNON SuiteSignOn
TAX_OVERHAULING SuiteTax
WORKFLOW SuiteFlow
The following tables list the internal IDs for all NetSuite preference configuration pages that support
SuiteScript.
To interact with a configuration page, load the page using config.load(options). After the page loads, you
can get or set configuration values using the returned record.Record object. Additionally, you can use
User.getPreference(options) to get the values for General Preferences and Accounting Preferences.
NetSuite configuration preference IDs are grouped into the following categories:
■ General Preferences
■ Company Information
■ User Preferences
■ Accounting Preferences
■ Accounting Periods
■ Tax Setup
■ Tax Periods
General Preferences
These are the account preferences that can be found by going to Setup > Company > General
Preferences.
The internal ID for the General Preferences page is companypreferences. All preference internal IDs are
case-insensitive.
Company Information
The Company Information preferences are available at Setup > Company > Company Information.
To interact with these preferences, use the COMPANY_INFORMATION value from the config.Type enum. All
Company Information preference IDs are case-sensitive.
For details about working with the Company Information page in the UI, see the help topic Configuring
Company Information.
Note: The Company Information page includes several preferences that are displayed as body
fields. These fields are described in the following table.
County/State/Province state
Country country
Fax fax
Currency basecurrency
Account ID companyid
These three IDs represent text summaries of the data that exists on the three mainaddress _text
address subrecords.
shippingaddress _text
returnaddress _text
The Company Information page also includes gray boxes with the headings Address, Shipping Address,
and Return Address. In the UI, you interact with these components by clicking the Edit link next to each
box. Clicking any of these links displays a popup window that includes more fields.
To interact with these fields programmatically, you must use subrecord methods to access the fields
associated with the Address, Shipping Address, and Return Address blocks. You must first instantiate the
appropriate subrecord by using Record.getSubrecord(options). This method requires one argument: the
ID of the subrecord. For the address subrecords on the Company Information page, use the following
internal IDs:
■ mainaddress
■ shipaddress
■ returnaddress
After you instantiate the subrecord, you can interact with any of the preferences shown in the following
table. These preferences are handled as fields on each subrecord instance.
Address1 addr1
Address2 addr2
Attention attention
Addressee addressee
Phone addrphone
City city
County/State/Province state
Zip zip
Country country
For an example, see the help topic Retrieving a Body Field Address Subrecord Example. For general
information about subrecords, see the help topic SuiteScript 2.x Scripting Subrecords.
User Preferences
These are the user preferences that can be found by going to Home > Set Preferences.
The internal ID for the user preferences page (which appears as the Set Preferences page in the UI) is
userpreferences. All preference internal IDs are case-sensitive.
Be aware that the API for setting user preferences works the same as the UI in terms of setting a
preference for a user's session or setting it permanently. In the UI if a user sets a preference, and the
preference reverts back to a default setting on the user's next login, the same behavior is supported in
SuiteScript.
Nickname MESSAGE_NICKNAME
Signature MESSAGE_SIGNATURE
Language LANGUAGE
E-Mail EMAILALERT_EMAIL
Subsidiary SUBSIDIARY
Department DEPARTMENT
Location LOCATION
Class CLASS
Accounting Preferences
These are the account preferences that can be found by going to Setup > Accounting > Accounting
Preferences. All preference internal IDs are case-insensitive.
Requisitions CUSTOMAPPROVALPURCHREQ
Invoices CUSTOMAPPROVALCUSTINVC
Accounting Periods
These are the account preferences that can be found by going to Setup > Accounting > Manage G/L >
Manage Accounting Periods.
The internal ID for the Accounting Periods page is accountingperiods. All preference internal IDs are
case-insensitive.
Manufacturing Preferences
These are the manufacturing preferences that can be found by going to Setup > Manufacturing >
Manufacturing Preferences.
The internal ID for the Accounting Periods page is manufacturingpreferences. All preference internal
IDs are case-insensitive.
Tax Setup
The internal ID for the Set Up Taxes page is taxpreferences. All preference internal IDs are
case-insensitive.
Preference IDs for fields on this page vary according to the country of the nexus. Field internal IDs are
suffixed with the nexus country code. The format for these preferences is <field internal id><nexus
country code>. Be aware that different fields are available for different nexuses.
The table below shows some scriptable tax preference fields for a US nexus. Fields are suffixed with us,
for the US nexus. This table is provided for example purposes.
Field IDs in your account may be suffixed with a different nexus country code. And different fields may be
available. You may be able to look up field IDs in the user interface, by going to Setup > Accounting > Set
Up Taxes, and clicking on a nexus.
■ To make field IDs available, go to Home > Set Preferences and ensure that the Show Internal IDs box
is checked on the General subtab, Defaults area.
■ Find the field in the NetSuite user interface and click the field label to display the field level help text.
The field ID is displayed in the popup.
Tax Periods
These are the tax preferences that can be found by going to Setup > Accounting > Taxes > Manage Tax
Periods.
The internal ID for the Tax Periods page is taxperiods. All preference internal IDs are case-insensitive.
Task IDs
Applies to: SuiteScript 2.x | SuiteCloud Developer
Task IDs identify NetSuite pages. Each NetSuite page has a unique task ID.
You can reference task IDs when using the url.resolveTaskLink(options) and redirect.toTaskLink(options)
methods.
Button IDs
Applies to: SuiteScript 2.x | SuiteCloud Developer
The following table lists the internal IDs for standard NetSuite buttons that support SuiteScript.
These buttons may appear as inline buttons or as actions in the Actions menu for some records. The
following properties of the serverWidget.Button object can be used to customize buttons and actions:
■ Button.label – Use this property to change the label of the button or action.
■ Button.isHidden – Use this property to hide or show the button or action.
■ Change the display type of a button from an inline button to an action in the Actions menu, or from an
action to an inline button.
■ Add or remove a custom button to or from the Actions menu.
You can use point-and-click customization to change the display type of buttons and actions. For more
information, see the help topic Configuring Buttons and Actions.
Important: Customizing the Save, Edit, Cancel, Back, and Reset buttons is not supported in
SuiteScript or in point-and-click customization.
Accept accept
Apply apply
Approve approve
Bill bill
Close closeremaining
Convert convertlead
Credit credit
Decline decline
Delete delete
Email email
Fax fax
Fulfill process
GL Impact glimpact
Go To Register gotoregister
Grab grab
Memorize memorize
Merge merge
New new
Print print
Recalc recalc
Receive receive
Refund refund
Reject reject
Renew renewal
Reset resetter
Save As submitas
Search search
Tentative tentative
Unbuild createunbuild
Void void
W4 Worksheet w4data
You can use UI objects to build an assistant in NetSuite that has the same look-and-feel as other built-in
NetSuite assistants.
For additional information about NetSuite Assistants, see Understanding NetSuite Assistants.
For Working with UI Objects in SuiteScript 2.x, see the help topic SuiteScript 2.x Working with UI Objects.
In NetSuite, assistants contain a series of steps that users must complete to accomplish a larger task. In
some assistants, users must complete the steps sequentially. In others, steps are non-sequential, and
they do not all have to be completed. In these assistants, steps are provided only as guidelines for actions
users might want to take to complete a larger task.
The UI objects you use to construct your own assistant will encapsulate the look-and-feel of assistants
already built in to NetSuite. For examples of these assistants, see these topics:
■ SuiteBundler Assistant
■ Import Assistant
SuiteBundler Assistant
The SuiteBundler Assistant is another built-in NetSuite assistant. This assistant guides users through a
set of steps in custom NetSuite solutions that are “bundled,” later to be deployed into other NetSuite
accounts.
Note: To access the SuiteBundler Assistant, go to Customization > SuiteBundler > Create Bundle.
This figure shows Step 1 (page 1) of the SuiteBundler Assistant. Steps are ordered sequentially and
appear horizontally, directly below the title of the assistant.
All components called out in this figure can be built in a custom assistant.
1 Assistant title
4 Splash screen
Import Assistant
The Import Assistant guides users through a set steps that allow them to import data into NetSuite.
Note: To access the Import Assistant, go to Setup > Import/Export > Import CSV Records.
The following figure shows what an error message looks like in an assistant. Users cannot proceed to
the next step until the error is resolved. When building custom assistants, you can also throw errors that
prevent users from moving to the next step.
In NetSuite, you can build SPAs that match the NetSuite look and feel using the User Interface Framework
(UIF), with full SuiteScript support and SuiteCloud Development Framework (SDF) deployment capabilities.
See the following help topics for information about SPAs in NetSuite:
To learn more about SPAs and how to use them in NetSuite, see the following topics:
In contrast, with multi-page applications, every time you request new information, the browser loads a
whole new page instead of only updating the parts that changed.
SPAs convert data to HTML in the client (browser), instead of converting data in the server and sending it
back to the client.
■ More dynamic and seamless user experience. You get real-time updates without reloading the page or
resubmitting the form.
■ Faster loading and less bandwidth consumption compared to HTML.
■ Easier to debug and maintain because the presentation and application are kept separate.
■ Built-in NetSuite look and feel.
For information about the setup requirements for developing SPAs in NetSuite, see Single Page
Application Creation And Development.
■ NetSuite User Interface Framework (UIF) – The NetSuite frontend framework for building user
interfaces in JavaScript. This UI library loads by default when you run an SPA. You can use it in SPAs
to get the NetSuite look and feel. UIF uses features such as JSX syntax and ECMAScript module
management.
■ Single Page Application (SPA) – A web application that dynamically updates the page when you
interact with it, without fully reloading.
In NetSuite, SPAs are built as part of an SDF SuiteApp project and includes these components:
□ SPA client script – This script runs the application in your browser. It loads the components and
can also load SuiteScript modules and custom modules.
□ SPA server script – This script is the entry point for the application and has an API to modify the
response (add scripts, perform validations, etc.). For example, the application can show an error if
the user doesn't have a specific role.
□ Assets folder – This folder holds all the assets for the SPA (images, stylesheets, subfolders,
etc.). You can access these assets through the SPA asset endpoint /spa-app/<ApplicationID>/
<SpaFolder>/assets/<path_to_asset>, where <path_to_asset> is the file's relative path in the assets
folder.
□ SPA object definition – The XML file that defines the SPA object in the SDF SuiteApp project. It
sets the SPA name, URL, references to the SPA folder and script files. In SDF, SPAs are defined
as a singlepageapp SDF custom object. For more information, see the help topic Single Page
Applications as XML Definitions.
■ SPA URL – The link you use to run the SPA. It's made of up of:
□ Base URL – Where you access your NetSuite account.
□ Application ID – The SuiteApp application ID, made up of the publisher ID and project ID from
when you created the SDF SuiteApp project for the SPA.
□ Custom URL – The custom URL you set in the SPA object definition XML file.
Here's an example of an SPA URL: https: <AccountID>.app.netsuite.com/
spa-app/<ApplicationID>/<CustomURL>.
■ SuiteApps – Applications or bundles that extend NetSuite for specific industry and business needs.
You use SuiteApp projects created with SDF to develop and deploy SPAs in NetSuite. For more
information, see the help topic SuiteApp Projects.
■ SuiteCloud Development Framework (SDF) – A development framework you use to create
SuiteApps or customize NetSuite accounts using SuiteCloud projects. For information, see the help
topic SuiteCloud Development Framework.
■ SuiteCloud projects – Projects you create using SDF. There are two types: account customization
projects and SuiteApp projects. For information, see the help topic SuiteCloud Project Types.
NetSuite UIF and SuiteApps use different ways to manage modules. NetSuite UIF uses ECMAScript
Modules (ESM), whereas SuiteApps use RequireJS, which is based on the Asynchronous Module Definition
(AMD). Because of this, you need to convert SPA source files before you can deploy a SuiteApp project
with SPAs. The conversion process includes:
You also need a specific folder structure to set up SPAs and make sure the conversion process works as
expected. Each SPA in your SuiteApp project needs the following:
You can download sample SPA SuiteApps from the SuiteCloud Project Repository on Oracle Samples
GitHub and use them as templates for your own SPAs. These samples use the required folder structure
and include a file that handles (using Gulp) the build and bundle steps to convert the source files. You can
use the gulpfile from the samples, or use any standard tool you prefer to transpile and convert the files.
For more information, see Single Page Application Samples.
■ SuiteApp Project Structure for Single Page Applications – Describes the required folder structure for
SPAs.
■ Build Process for SuiteApp Projects with Single Page Applications – Describes how the gulpfile works
and the supported build tasks.
■ NetSuite User Interface Framework for Single Page Applications – Provides information about NetSuite
UIF.
You can find sample SuiteApp projects with SPAs in the SuiteCloud Project Repository on Oracle Samples
GitHub. For more information, see Single Page Application Samples.
For information about SDF SuiteApp projects, see the help topics SuiteApp Projects and SuiteCloud
Project Structure and File Components.
■ /src/SuiteApps/<ApplicationID>/<SpaFolder> – This SPA folder holds the SPA server script, SPA client
script, and the application's root component. It can also include the assets folder for static files.
■ /test – Holds unit tests and test stubs.
■ /src/manifest.xml and /src/deploy.xml – These files contain the SuiteApp configuration.
■ /src/Objects/custspa_xxx.xml – The XML object definition file for the SPA SDF custom object.
■ /src/FileCabinet/SuiteApps/<ApplicationID>/<SpaFolder> – This folder holds the transpiled and
converted sources that get pushed to NetSuite when you deploy the SuiteApp. You can use the
gulpfile from the sample SPA projects to run the build and bundle tasks that convert the SPA source
files (see Build Process for SuiteApp Projects with Single Page Applications). Or, you use your own tool
to transpile and convert the files, and save the converted files in this folder.
Note: All JavaScript files in the src/FileCabinet/SuiteApps folder must use the Asynchronous
Module Definition (AMD) format.
If you have non-SPA script files in your SuiteApp project, take note of the following when using the
gulpfile from the sample projects:
■ If you have JavaScript and AMD script files, save them directly in the /src/FileCabinet/SuiteApps/
<ApplicationID> folder. Keep them outside the SPA folder (if it already exists) because the gulpfile
regenerates that folder each time you run a bundle task.
■ Don't place AMD script files inside the /src/SuiteApps/<ApplicationID>/<SpaFolder>. The gulpfile
assumes that all files in that folder are in ECMAScript Modules (ESM) format. If you include AMD
scripts, the gulpfile treats them as ESM and tries to convert them to AMD, which causes errors.
■ The gulpfile only processes files inside the SPA folders, anything outside is ignored. If you want to
place scripts in the /src/SuiteApps/<ApplicationID> folder, you'll need to handle building, bundling,
and moving those scripts to the src/FileCabinet/SuiteApps/<ApplicationID> folder for deployment.
■ The gulpfile is designed specifically for converting SPA scripts. If you want to use it to convert
non-SPA scripts in TypeScript and ESM, you'll need to handle any errors that may occur during this
process.
For more information about the gulpfile, see Build Process for SuiteApp Projects with Single Page
Applications.
The following shows a sample folder structure for an SPA SuiteApp after running the build and bundle
tasks implemented in the gulpfile.
<ApplicationID>
├── build/
├── node_modules/
├── src/
│ ├── FileCabinet/
│ ├── SuiteApps/<ApplicationID>/
│ ├── <OtherScripts>/
│ ├── <SpaFolder>/
│ ├── assets/
│ ├── SpaClient.js
│ └── SpaServer.js
│ └── Web Site Hosting Files/
│ ├── InstallationPreferences/
│ ├── Objects/
│ └── custspa_helloworld.xml
│ ├── SuiteApps/<ApplicationID>/
│ ├── <SpaFolder>/
│ ├── assets/
│ ├── HelloWorld.tsx
│ ├── SpaClient.tsx
│ └── SpaServer.tsx
│ ├── Translations/
│ ├── deploy.xml
│ └── manifest.xml
├── test/
├── gulpfile.mjs
├── jest.config.js
├── package.json
├── suitecloud.config.js
├── tsconfig.json
└── tsconfig.test.json
For information about how these tasks are used in the SPA creation process, see Single Page Application
Creation And Development.
For information about the sample SPA SuiteApps, see Single Page Application Samples.
Optionally, you can configure the source concatenation and minification settings in the gulpfile using
these variables:
■ concatenateScripts – Set the value to true to concatenate or bundle the sources for each entry point
into a single file. Doing so can help reduce the number of requests and loading time. Set the value to
false to disable concatenation.
■ minifyScripts – Set the value to true to remove unnecessary characters from the source code to
decrease file size. Doing so can help save bandwidth and improve web performance. Set the value to
false to disable minification.
■ Identify SPA folders by searching for directories that contain an SpaServer script
■ Within each SPA folder, search for these entry points: SpaClient scripts, SpaServer scripts, and any
script file containing the @NScriptType tag.
This task transpiles all the source files from using import and export statements to define and require
statements. It also takes into account the concatenateScripts and minifyScripts options defined in the
gulpfile.
The results are saved in /src/FileCabinet/SuiteApps/<ApplicationID>/<SpaFolder> and is ready to
be deployed to the target NetSuite account. This task also copies all asset files from /src/SuiteApps/
<ApplicationID>/<SpaFolder> to /src/FileCabinet/SuiteApps/<ApplicationID>/<SpaFolder>. Any file in
the SPA folder that is not a JavaScript or a TypeScript file is considered an asset.
1. The SPA URL is accessed by clicking a link to the SPA or manually entering the URL in a browser.
2. The associated SPA server script runs before any client-side code is served to the browser.
The SPA server script implements and exports the initializeSpa function. This function receives a
context parameter object, which contains an API that can modify the response by adding styles.
The system verifies whether the current user is part of the allowed audience specified in the SPA
definition. Next, it runs the initializeSpa function from the SPA server script.
3. The SPA client script is loaded when the rest of the page elements (that is, the NetSuite center)
have finished loading.
The SPA client script implements and exports the run function, which is the entry point function
called when the SPA runs. This function can return a promise or any other type of data.
The SPA client script loads the root component where the application is initialized.
The SPA displays a loading icon until the run entry point function returns. If it returns a promise,
the SPA displays a loading icon until the promise has been resolved or rejected.
4. The content of the SPA appears in the browser.
For information about creating SPAs, see Single Page Application Creation And Development.
You can find the following sample SPA SuiteApps in the repository:
■ Airport 360 – Sample 360-type SuiteApp that demonstrates the use of various NetSuite UI Framework
(UIF) features such as routing, side menu, state management, asynchronous loading, and SuiteScript
APIs.
■ Basics Routing – Demonstrates the basic principles of routing.
■ Basics State Management – Demonstrates the basic principles of state management.
■ Hello World JS – Minimal Hello World application written in JavaScript.
■ Hello World TS – Minimal Hello World application written in TypeScript.
■ Item 360 – Sample 360-type SuiteApp that demonstrates common SPA patterns and data handling
using SuiteScript.
1. Create the SDF SuiteApp project where you will implement your SPA. Alternatively, you can use
one of the sample SPA SuiteApps as a starting point or you can add SPAs to an existing SuiteApp
project.
2. Within the SuiteApp project, create the following for each SPA implementation:
■ A unique SPA folder
■ Two required scripts: SPA client script and SPA server script
■ An SPA object definition file
■ (Optional) An assets folder
If you are using a sample project, ensure that you update the folder names, file names, and the
contents based on your project.
3. Develop your application. Use the UI components and APIs from NetSuite UIF to build your SPA.
You also can use SuiteScript modules in the SPA client script and SPA server script.
4. Convert your SPA source files and build the SuiteApp. The sample SPA projects contain a gulpfile
that implements the build and bundle steps to convert the SPA source files. You can use this file
or you can opt to use your preferred tool to transpile and convert the files.
5. Validate and deploy your SuiteApp project.
6. Open your single page application in NetSuite.
■ Creating a Single Page Application – Describes how to create an SDF SuiteApp project that includes
SPAs.
■ Single Page Applications as XML Definitions – Provides information about the XML definition for an SPA
(singlepageapp) SDF custom object.
■ Developing Single Page Applications – Describes how to develop the SPA client script and SPA server
script.
■ Troubleshooting Single Page Applications – Provides information about errors related to SPAs.
For information about the sample SPA SuiteApps, see Single Page Application Samples.
■ Must use SuiteCloud Development Framework (SDF) SuiteApp projects (see the help topic SuiteApp
Projects)
■ Must use SuiteScript 2.1
You can use the UI components and APIs provided in the NetSuite User Interface Framework (UIF) to
build SPAs with NetSuite look and feel.
Before you can start developing SPAs, you must ensure that you have set up the following prerequisites in
your account:
■ Client SuiteScript
■ Server SuiteScript
Enable the SuiteCloud Development Framework (SDF) feature and set up the SuiteCloud Development Framework
requirements for SDF. Setup
Install Node.js from Node.js Downloads (if you do not have it installed). —
Set up your preferred development tool. You can choose from the following SuiteCloud Plug-ins and Extensions
SuiteCloud Software Development Kit (SDK) tools:
SuiteCloud CLIs
■ SuiteCloud Plug-ins and Extensions:
□ SuiteCloud Extension for Visual Studio Code
□ SuiteCloud IDE Plug-in for WebStorm
■ SuiteCloud CLIs:
□ SuiteCloud CLI for Java
□ SuiteCloud CLI for Node.js
Before you start, make sure you have completed the prerequisite tasks and you have read and
understood the concepts discussed in the following topics:
■ Components and Structure of Single Page Applications – Describes the project folder structure
required to implement SPAs.
■ NetSuite User Interface Framework for Single Page Applications – Describes how to access and use
NetSuite UIF to develop SPAs.
■ Single Page Application Samples – Provides sample SPA SuiteApps, from basic SuiteApps that you
can use as a template to more complex SuiteApps that demonstrate NetSuite UIF features and use
SuiteScript to handle data.
■ Prerequisites for Single Page Applications – Describes the prerequisite setup tasks that must be
completed before working on SPAs.
Note: If you plan to create an SPA using SuiteCloud IDE Plug-in for WebStorm, keep in mind that
the SPA object type is not listed in the New Custom Object window.
Similarly, script templates for the SPA client script and SPA server script are not available when you
select a new SuiteScript file. You need to manually create the SPA object definition and SPA script
files. Alternatively, you can use the sample SPA SuiteApps as a starting point, or you can copy the
structure from an existing SPA.
<dependencies>
<features>
<feature required="true">SERVERSIDESCRIPTING</feature>
</features>
</dependencies>
4. Create the following files and folders for each SPA implementation.
If you are using a sample SuiteApp project as a template, ensure that you update the folder names,
file names, and contents based on your project.
a. SPA folder (src/SuiteApps/<ApplicationID>/<SpaFolder>) – This folder is where you will
store your source files for your SPA. Each SPA implementation in the SuiteApp project must
have a unique folder. Inside each SPA folder, you can organize your files into sub-folders. For
guidance on creating and organizing the folder for your source files, see SuiteApp Project
Structure for Single Page Applications.
b. SPA client script and SPA server script – If you copied the folder from the sample project,
the SpaClient and SpaServer scripts with the minimum required content are already
included the src/SuiteApps/<ApplicationID>/<SpaFolder> folder. You can use these scripts
as a starting point. You can also change the file names if you prefer. For information about
the script structure and examples of SuiteScript modules that you can add to these scripts,
see Developing Single Page Applications.
If you want to create these scripts manually, ensure that you save them inside the SPA
folder.
c. SPA assets folder (src/SuiteApps/<ApplicationID>/<SpaFolder>/assets) – This folder is
optional and, if available, must be located inside the SPA folder. It can be used to store
assets such as style sheets and images. These assets can be accessed by your SPA through
the asset endpoint /spa-app/<ApplicationID>/<SpaFolder>/assets/<path_to_asset>, where
<path_to_asset> is the relative path to the asset file within the assets folder.
For example, an image located at src/SuiteApps/com.netsuite.spa/helloworld/assets/
logo.png can be accessed using the endpoint: /spa-app/com.netsuite.spa/helloworld/
assets/logo.png.
d. SPA object definition XML file – You can copy the SPA object definition file from a sample
project, or you can manually create a new XML file for your SPA object. Save this file in the
src/Objects folder. If you are using the XML definition file from the sample project, be sure
to update the file name and edit its contents (such as the script ID and paths) to match the
details of your project.
SPAs are defined in SDF as a singlepageapp SDF custom object. For more information, see
the help topic Single Page Applications as XML Definitions.
Follow these guidelines for the SPA object XML definition file:
■ Each SPA implementation in the SuiteApp project must have its own SPA object definition
XML file stored in the Objects folder.
■ The scriptid specified in the object definition must match the file name of the SPA object
definition file.
■ The paths specified in the object definition are relative to the src/FileCabinet/ folder.
Take note of the following:
□ The target location for the SPA folder must be inside src/FileCabinet/SuiteApps/
<ApplicationID>/ (where the transpiled files will be saved after running the build). In
the XML definition, you do not need to include src/FileCabinet in the path.
□ The path specified for the SPA client script (clientscriptfile) and SPA server script
(serverscriptfile) must point to a location inside the SPA folder.
□ The assets folder is optional. If you provided a folder path in the assetsfolder field
of the SPA object definition, then you also need to have the assets folder in the SPA
folder.
The basic XML definition for an SPA object in a SuiteApp looks like the following:
<singlepageapp scriptid="custspa_helloworld">
<name>Hello World</name>
<description>This is a sample SuiteApp that uses NetSuite UIF components.</description>
<url>helloworld-suiteapp-spa</url>
<folder>[/SuiteApps/com.netsuite.spa/helloworld/]</folder>
<clientscriptfile>[/SuiteApps/com.netsuite.spa/helloworld/SpaClient.js]</clientscriptfile>
<serverscriptfile>[/SuiteApps/com.netsuite.spa/helloworld/SpaServer.js]</serverscriptfile>
<assetsfolder>[/SuiteApps/com.netsuite.spa/helloworld/assets/]</assetsfolder>
</singlepageapp>
For a complete example showing all the supported fields, see the help topic Single Page
Application XML Definition Example.
5. Create the root component for your SPA, and save the script file inside the appropriate folder
under src/SuiteApps/<ApplicationID>/<SpaFolder>.
Go to NetSuite UIF for information about the components and APIs that you can use to develop
your SPA. To access NetSuite UIF, copy this URL to your browser and replace <AccountID> with your
NetSuite account ID: https://<AccountID>.app.netsuite.com/ui/apps/catalog.nl.
If you want to use the NetSuite UIF TypeScript type declarations, follow these steps to install the
@netsuite-uif-types package:
1. In the package.json file, add @oracle/suitecloud-uif-types and typescript to the
devDependencies and specify the appropriate version based on the NetSuite version that
you are developing for.
For example:
"devDependencies": {
"@oracle/suitecloud-uif-types": "^7.0.0",
"typescript": "^5.2.0"
}
"compilerOptions": {
"typeRoots": {
"node_modules/@types",
"node_modules/@oracle/suitecloud-uif-types"
}
}
Important: After defining the root component, you must import the component from
the SPA client script and provide it as a parameter to the setContent(rootComponent)
method. For more information, see Single Page Application Client Script.
At this point, your SuiteApp project folder structure should look something like the following:
com.netsuite.spa
├── src/
│ ├── FileCabinet/
│ ├── SuiteApps/com.netsuite.spa/
│ └── Web Hosting Files
│ ├── InstallationPreferences/
│ ├── Objects/
│ └── custspa_helloworld.xml
│ ├── SuiteApps/com.netsuite.spa/
│ └── helloworld/
│ ├── assets/
│ ├── HelloWorld.tsx
│ ├── SpaClient.tsx
│ └── SpaServer.tsx
│ ├── Translations/
│ ├── deploy.xml
│ └── manifest.xml
├── test/
├── gulpfile.mjs
├── jest.config.js
├── package.json
├── suitecloud.config.js
├── tsconfig.json
└── tsconfig.test.json
6. Build the SuiteApp. The build process transpiles the source files in the src/SuiteApps/
<ApplicationID>/<SpaFolder> folder and stores the converted files in the src/FileCabinet/
SuiteApps/<ApplicationID>/<SpaFolder> folder.
You can use any standard tool to transpile and convert your SPA source files, or you can use
the gulpfile provided in the sample SPA SuiteApp projects. For more information about the
tasks implemented in the gulpfile, see Build Process for SuiteApp Projects with Single Page
Applications.
To use the gulpfile, open a terminal or command line, and run the following NPM tasks from the
src folder:
■ npm i – To install build dependencies.
■ npm run build – To build the project. This task runs the TypeScript compiler on the files in src/
SuiteApps/<ApplicationID>/<SpaFolder> and saves the result in a new build folder.
■ npm run bundle – To bundle the SuiteApp. This task takes the transpiled sources from the
build folder and bundles them together. The result is saved in src/FileCabinet/SuiteApps/
<ApplicationID>/<SpaFolder> and is ready to be deployed to the target NetSuite account.
After building the SuiteApp, your project folder structure should look something like the following:
com.netsuite.spa
├── build/
├── node_modules/
├── src/
│ ├── FileCabinet/
│ ├── SuiteApps/com.netsuite.spa/
│ └── helloworld
│ ├── assets/
│ ├── SpaClient.js
│ └── SpaServer.js
│ └── Web Hosting Files
│ ├── InstallationPreferences/
│ ├── Objects/
│ └── custspa_helloworld.xml
│ ├── SuiteApps/com.netsuite.spa/
│ └── helloworld/
│ ├── assets/
│ ├── HelloWorld.tsx
│ ├── SpaClient.tsx
│ └── SpaServer.tsx
│ ├── Translations/
│ ├── deploy.xml
│ └── manifest.xml
├── test/
├── gulpfile.mjs
├── jest.config.js
├── package.json
├── suitecloud.config.js
├── tsconfig.json
└── tsconfig.test.json
7. Validate and deploy the SuiteApp project. If you are using the gulpfile, you can run npm run
deploy to bundle and deploy the SuiteApp to the target NetSuite account.
If you prefer to deploy the SuiteApp from your NetSuite SDK development tool, see References to
SuiteCloud SDK Tools for guidance on how to perform this task.
8. When the SuiteApp is successfully deployed, you can open the single page application in NetSuite.
■ To see the list of single page applications in your account, go to Customization > Scripting >
Single Page Applications. To open the management page for an SPA, click the SPA name.
■ To open a single page application:
□ From the SPA list, click the link icon next to the SPA name.
□ From the SPA record, click the link in the URL field.
After setting up the SPA SuiteApp project, you can continue to develop and configure your SPA. For more
information about these topics, see Developing Single Page Applications and Single Page Application
Management.
Note: All code samples in this section use import, so they need to be transpiled before
deployment to NetSuite. For more information, see Components and Structure of Single Page
Applications and Creating a Single Page Application.
For information about the execution process of SPAs, see Understanding the Single Page Application
Execution Process.
You can load SuiteScript modules from the SPA client script. For examples, see SPA Client Script Basic
Examples using SuiteScript modules.
1. It includes a run(context) entry point function in the return statement. This function can return
any type of data, including a promise.
2. The entry point function can receive an object that provides access to data or methods. In this
case, the context object has the following properties:
■ baseUrl – URL of the SPA.
■ The context object also exposes two functions:
□ context.setLayout(LayoutType) – Sets the LayoutType property of the Shell component.
This method accepts the following values for the LayoutType parameter:
LayoutType string application Makes the content fill the whole height of the window.
For example, it enables you to place some things on
the bottom of the window.
rootComponent NetSuite UIF The root component for the SPA, represented as
component a NetSuite UIF component. The root component is
defined in a separate script file.
In the following example, the layout type is set to application using the setLayout(LayoutType)
method. The SPA client script imports the root component from the HelloWorld.js file. To set the
page context, the setContent(rootComponent) method is used to render the HTML element of the
HelloWorld component, which is defined in the HelloWorld.js file
3. The HelloWorld.js file is a separate script file that defines the root component that initializes the
SPA using NetSuite UIF.
The following example shows how to load an existing employee record using the N/record Module, and
enter some value in the Notes field. Replace the value of the internal ID of the record with a valid value in
your account.
You can load most server-side SuiteScript modules from the SPA server script. For examples, see SPA
Server Script Basic Examples using SuiteScript modules.
1. It includes the two JSDoc tags, @NApiVersion and @NScriptType, declaring the appropriate version
(2.1) and script type (SpaServerScript).
/**
* @NApiVersion 2.1
* @NScriptType SpaServerScript
*/
2. It implements and exports an initializeSpa(context) entry point function. This function receives
a context parameter, an object that contains the context.addStyleSheet(options) method.
/**
* @NApiVersion 2.1
* @NScriptType SpaServerScript
*/
export const initializeSpa = (context) => {};
3. The context.addStyleSheet(options) method adds a style sheet to the SPA. It returns void.
This method has the following parameters:
relativePath string At least one is required (and The path to the CSS file relative to the assets
not null). folder (for example, "/main.css").
url string At least one is required (and The URL where the CSS file is located (for
not null). example, "http://sampleweb.com/css/main.css").
The URL member overrides any value provided
in the relativePath member.
The following example shows how to use the context.addStyleSheet(options) method with both
parameters specified. The url gets precedence over the relativePath.
/**
* @NApiVersion 2.1
* @NScriptType SpaServerScript
*/
import log from 'N/log';
/**
* @NApiVersion 2.1
* @NScriptType SpaServerScript
*/
import runtime from 'N/runtime';
The following sample adds a custom.css style sheet, located in the folder <folder>/<assetsfolder>/css/.
/**
* @NApiVersion 2.1
* @NScriptType SpaServerScript
*/
■ Validation and Deployment Errors – Describes errors that may occur when you validate and deploy an
SDF SuiteApp project that contains an SPA object.
■ Execution Errors – Describes errors that may occur when you run an SPA.
When the SuiteCloud project The SERVERSIDESCRIPTING feature is Add the SERVERSIDESCRIPTING feature
contains a singlepageapp, missing in the manifest.xml file. to the manifest.
the manifest must define the
SERVERSIDESCRIPTING feature as
required.
The object script ID must not be The scriptid is empty or it does not Specify a script ID in the SPA object
empty and must start with custspa. start with custspa. definition file and ensure that it starts
with the prefix custspa.
The object field name is missing. The name field is missing. Add the name field and specify a value
for it.
The object field name must not be The name field is empty. Specify a value for the name field.
empty.
The object field url is missing. The url field is missing. Add the url field and specify a value
for it.
The object field url must not be The url field is empty. Specify a unique value for url.
empty.
The object field folder is missing. The folder field is missing. Add the folder field and specify a
value for it.
The object field folder must not be The folder field is empty. Specify a unique value for folder.
empty.
The object field clientscriptfile is The clientscriptfile field is missing. Add the clientscriptfile field and
missing. specify a value for it.
The object field serverscriptfile is The serverscriptfile field is missing. Add the serverscriptfile field and
missing. specify a value for it.
The object field clientscriptfile must The value of the clientscriptfile field Specify a value for the
not be empty. is missing. clientscriptfile field.
The object field serverscriptfile must The value of the serverscriptfile field Specify a value for the
not be empty. is missing. serverscriptfile field.
The linkcategory field is missing for The link sublist element is included in Add the linkcategory field and specify
the (link) subrecord. the SPA object definition, but there is a value for it.
no linkcategory field inside it.
The linklabel field is missing for the The link sublist element is included in Add the linklabel field and specify a
(link) subrecord. the SPA object definition, but there is value for it.
no linklabel field inside it.
The linkcategory field for the (link) The linkcategory field is empty. Specify a value for the linkcategory
subrecord must not be empty. field.
The linklabel field for the (link) The linklabel field is empty. Specify a value for the linklabel field.
subrecord must not be empty.
Incorrect Format
The scriptid value must be lowercase The value for scriptid Ensure that the value for
alphanumeric without spaces or punctuation. contains characters not scriptid contains only lowercase
Underscores are permitted. allowed in the ID field. alphanumeric characters and
underscores.
The script ID must not exceed 28 characters. The value for scriptid has Ensure that the value for scriptid
more than 28 characters. is limited to 28 characters.
The name field contains more than the The value for name has more Ensure that the value for name is
maximum number (1000) of characters allowed. than 1000 characters. limited to 1000 characters.
The description field contains more than the The value for description has Ensure that the value for
maximum number (1000) of characters allowed. more than 1000 characters. description is limited to 1000
characters.
The url field contains more than the maximum The value for url has more Ensure that the value for url is
number (1000) of characters allowed. than 1000 characters. limited to 1000 characters.
The URL cannot contain the following The value for url contains Ensure that the value for url does
characters: ? ! * ' ( ) ; : @ & = +$ , / ? # [ ] . spaces or some of the not contain spaces or any of the
characters that are not allowed.
The {folder value} folder value referenced by the The value for folder is entered Ensure that the value for folder
folder object field must start and end with the in the wrong format. starts and ends with '/' and does
'/' character and must not contain the following not contain any of the following
characters: ?, *, <, >, |, ', \\ . characters: ? * < > | ' \\.
The folder name, {folder name}, must not The folder name has more Ensure that the folder name is
exceed 99 characters. than 99 characters. limited to 99 characters.
The filename [filename] must not exceed 199 The client script file name, Ensure that the file name is
characters. including the file extension, limited to 199 characters,
has more than 199 characters. including the file extension.
The filename [filename] must not exceed 199 The server script file name, Ensure that the file name is
characters. including the file extension, limited to 199 characters,
has more than 199 characters. including the file extension.
The file {folder value}/SpaClient referenced by The client script file does not Ensure that the client script file is
the field clientscriptfile is an invalid file type. have a file extension or has an a JavaScript file (.js).
The file name can only contain the following file incorrect file extension.
extension(s): .js. Change the file name reference
and then try again.
The file {folder value}/SpaServer referenced by The server script file does not Ensure that the server script file is
the field serverscriptfile is an invalid file type. have a file extension or has an a JavaScript file (.js).
The file name can only contain the following file incorrect file extension.
extension(s): .js. Change the file name reference
and then try again.
The {assetsfolder} folder value referenced by The value for assetsfolder is Ensure that the value for
the assetsfolder object field must start and end entered in the wrong format. assetsfolder starts and ends with
with the '/' character and must not contain the '/' and does not contain any of the
following characters: ?, *, <, >, |, ', \\. following characters: ? * < > | ' \\.
The folder name, {<assets folder name>}, must The assets folder name has Ensure that the assets folder
not exceed 99 characters. more than 99 characters. name is limited to 99 characters.
The linklabel field contains more than the The linklabel field has more Ensure that the value for
maximum number (30) of characters allowed. than 30 characters. linklabel is limited to 30
characters.
The notifyemails field contains more than the The value for notifyemails Ensure that the value for
maximum number (999) of characters allowed. has more than 999 characters. notifyemails is limited to 999
characters.
Duplicate Values
This URL already exists. Please enter a The value for url is not unique and already Specify a unique value for
different one. exists in the account. url.
The URL <url> specified by the object field More than one SPA object is using the Specify a unique value for
url is already referenced by another object. specified URL. Each SPA must have a url.
Select a different URL and try again. unique URL.
The folder <folder> referenced by the The value for folder is not unique and Specify a unique value for
object field folder is already referenced by already exists in the account. folder.
Duplicate values {linkcategory value} There is more than one link element with Remove the duplicate
were found in the 'links' sublist on the the same value in the linkcategory field. values for the linkcategory
'singlepageapp' record. You cannot set more than one link for field.
each location.
Invalid Values
The object field executeas must not The value for executeas field does Ensure that the value specified in
be {x}. not correspond to any existing role. executeas is an existing role.
[ADMINISTRATOR] role cannot The value entered for the executeas Specify a role other than ADMINISTRATOR in
be used for the 'Execute As' field. field is ADMINISTRATOR. This value the executeas field.
Select a different value. cannot be used for this field.
The object field loglevel must not The value for loglevel is not valid. Set loglevel to any of the following:
be {x}. DEBUG, AUDIT, ERROR, or EMERGENCY.
The object field audienceroles must The value for audienceroles field Ensure that the value specified in
not be {x}. does not correspond to any existing audienceroles is an existing role.
role.
Use uppercase letters when entering a
generic role value.
The audienceallroles field must be The value for audienceallroles is Set audienceallroles to either T or F.
set to a valid Boolean value, 'T' or not valid.
'F'.
The object reference {executeas The custom role referenced in the Ensure that the custom role referenced in
value/audienceroles value} is executeas or audienceroles field executeas or audienceroles exists in the
missing in the project and also not does not exist in the project and is SuiteApp project.
included in the dependencies list. not included in the dependencies
list.
The linkcategory field for the The value in the linkcategory field Check the list of possible values
(link) subrecord must not be is not valid. for the center category in
{linkcategory value}. generic_centercategory. The linkcategory
field also accepts references to
centercategory custom type.
The {linkcategory value} object The linkcategory field value Check that the custom centercategory
referenced by the linkcategory field references an object that is missing object that you are referencing in the
in the (link) subrecord is missing. from the project. linkcategory field exists in your SuiteApp
project.
The notifyuser field must be set to The value for notifyuser is not Set notifyuser to either T or F.
a valid Boolean value, 'T' or 'F'. valid.
The notifyowner field must be set The value for notifyowner is not Set notifyowner to either T or F.
to a valid Boolean value, 'T' or 'F'. valid.
The notifyadmins field must be set The value for notifyadmins is not Set notifyadmins to either T or F.
to a valid Boolean value, 'T' or 'F'. valid.
The notifyemails field value The notifyemails field value is not a Ensure that the email address specified
is invalid. To include multiple valid email address or is entered in is valid and entered in the correct format.
addresses, separate them by the wrong format. Use a comma to separate multiple email
commas. addresses.
The script ID must match the file name The scriptid value specified in the object Specify the same value for
(excluding the file extension). definition does not match the SPA object the SPA object file name
file name. (custspa_<name>) and for the
scriptid attribute.
The folder field in the {/SuiteApps/ The <publisherid2>.<projectid2> does not Check that all of the following
<publisherid2>.<projectid2>/<folder match the <publisherid>.<projectid> of the values match:
name>} reference is invalid. manifest.xml or deploy.xml file.
■ The values in the
publisherid and projectid
fields in the manifest.xml
file
■ The value in the path
tag under files in the
deploy.xml file
■ The values used in the
folder field in the SPA
object definition file
The SPA folder is not within the application The folder path in the folder field Ensure that the SPA folder is inside
folder. points to a location outside of the / your local SuiteApp project folder src/
SuiteApps/<publisherid>.<projectid>/ FileCabinet/SuiteApps/<publisherid>.
The folder field in the {/SuiteApps/ folder. <projectid>/.
<publisherid>.<projectid>/<folder name>}
reference is invalid.
The folder {/SuiteApps/ The SPA folder specified in the Ensure that the SPA folder has been
<publisherid>.<projectid>/<folder>} folder field does not exist in the SDF created in your local project.
referenced by the object field folder is SuiteApp project folder.
missing.
The file {folder value}/SpaClient.js The client script file specified in Ensure that you have the SPA client
referenced by the object field clientscriptfile clientscriptfile does not exist script inside the SPA folder.
is missing. in the SPA folder inside the SDF
SuiteApp project.
The file {folder value}/SpaServer.js The server script specified in Ensure that you have the SPA server
referenced by the object field serverscriptfile does not exist script inside the SPA folder.
serverscriptfile is missing.
The folder {/SuiteApps/ The assets folder specified in the Ensure that the folder has been
<publisherid>.<projectid>/<folder>/assets/ assetsfolder field does not exist in created in your local project and is
} referenced by the object field assetsfolder the SDF SuiteApp project folder. inside the SPA folder.
is missing.
The client script is not within the SPA folder. The client script path points to a Check that the value in the
different folder than the SPA folder. clientscriptfile field uses the path
specified in the folder field.
The server script is not within the SPA The server script path points to a Check that the value in the
folder. different folder than the SPA folder. serverscriptfile field uses the path
specified in the folder field.
The assets folder is not within the SPA The assets folder path points to a Check that the value in the
folder. different folder than the SPA folder. assetsfolder field uses the path
specified in the folder field.
/SuiteApps/<publisherid2>.<projectid2>/ The client script path points to a Check that the value in
<folder name>/SpaClient.js is invalid. folder in a different application. the clientscriptfile field
The clientscriptfile field must start with / uses the correct value for
SuiteApps/<publisherid>.<projectid>/, /Web <publisherid>.<projectid>.
Site Hosting Files/.
/SuiteApps/<publisherid2>.<projectid2>/ The server script path points to a Check that the value in
<folder name>/SpaServer.js is invalid. folder in a different application. the serverscriptfile field
The serverscriptfile field must start with / uses the correct value for
SuiteApps/<publisherid>.<projectid>/, /Web <publisherid>.<projectid>.
Site Hosting Files/.
The assetsfolder field in the {/SuiteApps/ The assets folder path points to a Check that the value in the
<publisherid2>.<projectid2>/<folder folder in a different application. assetsfolder field uses the correct
name>/assets} reference is invalid. <publisherid>.<projectid> value.
Execution Errors
The following table describes the errors that may occur when executing your single page application
(SPA).
The requested SPA does not The SPA that you are trying to run does not exist in the —
exist. NetSuite account. The SPA may have been deleted, or the
URL entered for the SPA is incorrect.
The client script file cannot be The client script file, the server script file, or the SPA folder is —
loaded: the file is not active. marked as inactive.
The client script file cannot You do not have permission to access this file, or you do not —
be loaded: you do not have have access to the SuiteApps folder (for example, the folder
permission to access this file. access is restricted).
An error occurred while You accessed the SPA using a user or a role that does not —
executing the server script. have permission to view the SPA.
You do not have privileges to
view this page.
The client script file cannot The script tried to load a module that does not exist. For SCRIPT_FILE_DEPENDENCY_
be loaded: the script example: ERROR
dependencies cannot be
loaded. define(['N/module'], function(module) {
The entry point function The script does not have the run() function. For example: SCRIPT_DOES_NOT_HAVE_RUN_
cannot be called: the script MEMBER
does not have the specified define([], function() {
function. return {
test: function (context) {
}
};
});
The entry point function The run() function exists but is not well defined. For SCRIPT_MEMBER_NOT_
cannot be called: the function example, it is not defined as a function but as a variable: CALLABLE
exists but cannot be called.
define([], function() {
return {
run: 1
};
});
The entry point function The script does not expose any module. The script must SCRIPT_DOES_NOT_EXPOSE_
cannot be called: no define include one define function. You will also see this error if the ANY_MODULE
function found. return statement is missing or if other structure errors are
present. For example:
console.log('TEST');
The entry point function The script throws an error. For example: SCRIPT_ENTRY_POINT_
throws an exception. THROWS_ERROR
define([], function() {
return {
run: function (context) {
throw 'spaclient.js Error';
}
};
});
An error occurred while An unexpected error occurred during the execution of the —
rendering the SPA. SPA.
An error occurred while An error is thrown by the server script. For example: An —
executing the server script. error occurred while executing the server script.
{string thrown} Unauthorized user.
404 error The assets folder is included in the URL for the SPA, but it —
does not exist.
You can manage these settings both from the NetSuite UI and from SuiteCloud Development Framework
(SDF).
When updating an SPA object in an SDF SuiteApp project, consider the following information:
■ From the SDF perspective, if you change the SPA ID, the object is considered a new SPA with the new
ID. The SPA with the old ID is removed. However, you also need to update the URL and the SPA folder
before you validate or deploy the project. Otherwise, uniqueness validation errors will be thrown.
■ You cannot create new files or folders by only updating the XML definition. When you update the
XML definition to include a new file or folder, only the references are updated. You must create new
files and folders using the File Cabinet, or you can create them in your IDE and deploy them to your
account. For example, if you type a file or folder name incorrectly in the XML definition, this incorrectly
named file or folder is not created in the project. Instead, an error is thrown because the specified file
or folder cannot be found.
■ If you remove an optional field from your XML definition, the existing value is preserved and no
change is applied to the field (except for links that are removed).
■ For most optional fields, if you leave the value empty, it is reset to its default value. The exception is
the Boolean field notifyowner, which has a default value of true (T). If you leave the value for this field
empty, it is changed to false (F).
■ Setting the audienceallroles to true (T) selects all internal roles only. You can use the audienceroles
field to individually specify internal and external roles that can run the SPA. If audienceallroles is set
to true, all internal roles will be included in the audience along with any specific external roles listed in
audienceroles.
To update an SPA object, you must have the SuiteApp project files saved in your local environment (even
if you do not make changes to other files). Otherwise, when you redeploy the SuiteApp with the updated
SPA object, it will fail. If you do not have these files saved locally, you can import the SPA object from a
target NetSuite account into your SDF SuiteApp project and download the script files from the NetSuite
File Cabinet.
1. If you have the SuiteApp project files in your local environment, you can proceed directly to step 2.
Otherwise, follow these steps to download the SuiteApp project files:
1. Import the SPA object from a target NetSuite account to your local environment.
The Download XML button is not available for SPA objects, but you can use SuiteCloud
plug-ins and extensions and SuiteCloud CLI to import an SPA object from a NetSuite
account. For more information, see the help topic Account Component Imports to
SuiteCloud Projects.
You can import an object from a specific SuiteApp by specifying the application ID. To filter
your search, select singlepageapp as the object type and select script IDs that contain
custspa.
2. Download the SPA folder, SPA client script file, and SPA server script file, or create them in
your local environment. If the assetsfolder field has a value in the XML definition, you also
need to create an assets folder inside the SPA folder. The assets folder is not downloaded if
the folder is empty.
You cannot import files from a NetSuite account into a SuiteApp project. You must manually
download the SuiteApp project files from the NetSuite File Cabinet or create the files in your
local SuiteApp project folder.
2. In the SPA object definition XML file, change the fields that you want to modify. For information
about the XML definition for SPA objects, see the help topic Single Page Applications as XML
Definitions. For information about fields and possible values in the SPA object definition, see the
help topic singlepageapp.
3. Deploy the project to your account. For more information, see the help topic SuiteCloud Project
Deployment Preparation.
Note: You can apply installation preferences to SPAs. The SPA supports object locking,
and hiding and locking of files. For more information about installation preferences and
how to apply them, see the help topic Installation Preferences in the SuiteApp of SuiteCloud
Project.
■ To open the management page for an SPA, click the SPA name.
■ To open a single page application, click the link icon next to the SPA name.
Note: SPAs that are part of SuiteApps installed from the SuiteApp Marketplace have a limited
version of the SPA management page, where basic information is in read-only mode and only
configuration fields are editable. For information about managing SPAs from installed SuiteApps,
see the help topic Managing Single Page Applications Included in SuiteApps.
For developers working on SPAs, you can manage the SPA settings from these tabs on the SPA
management page:
■ Basic Info – Shows the details of the SPA, including the SPA name, SPA ID, name and ID of the
SuiteApp that the SPA is part of, SPA URL, and the SPA sources (SPA folders and script files). Click the
link icon next to the SPA source files to go to the location of the folder or file in the File Cabinet.
■ Configuration – Includes the configuration fields that you can edit to change the settings of the SPA.
For information about the changes that you can make on this tab, see Configuring Settings from the
SPA Management Page.
■ Logs – Shows the logs for the SPA. Click Refresh to reload the list and see any new logs after running
the SPA.
■ System Notes – Shows the changes for the SPA (creation and updates). The following details are
shown: date/time, user, role of the user, type of action, object changed, and old and new values. The
information about deletion actions is also retained.
Note: Updates to the values of following fields are not tracked by System Notes: Audience,
Center Links, and Error Notifications.
Execute As Determines the permissions and restrictions To change the role selected in this field, click the
to apply when running the SPA server script edit icon to display the list of available roles. Select
based on the selected role. By default, a role, and click Save.
this field is set to Current Role. For more
information, see Executing Scripts Using a
Specific Role.
Log Level Filters the log entries shown on the Logs tab. To change the log level, click the edit icon to
The default log level is Debug. Other log level display the log level options. Select a value, and
options include Audit, Error, and Emergency. click Save.
For more information, see Setting Script
Execution Log Levels.
Release Determines who can run the SPA. When the To change the audience, click the Set Up
Audience SPA is created, it runs only in the accounts Audience button to see the current roles selected
of the roles selected in this field. If no role and other possible options. You can filter the list
is specified, the SPA is accessible only to the by entering the name of the role.
script owner.
The audience roles are shown in two separate
multiselect fields: Internal Roles and External
Roles.
Center Links Lets you create, edit, or delete center links ■ To create a center link, click the Add Link
for the SPA. Center links are used to specify button. On the Center Link window:
a menu path that lets users access the SPA
□ In the Menu Location field, select the
directly from that location.
center and tab where you want to add the
SPA link. By default, the new link is added
at the bottom of the list in the location you
specify. If you want your link to be inserted
before an existing element, select a value in
the Insert Before field.
□ In the Label field, enter the label for the SPA
link.
Click Save. You need to reload the page to
see the new link from the menu location you
specified. You can add only one link per menu
location.
■ To edit an existing center link, click the edit icon
and edit the fields that you want to update.
Click Save.
■ To delete an existing center link, click the delete
icon, then click the Delete Link button.
Error Indicates who is notified about errors. By To set up the list of users who receive notifications,
Notification default, the script owner is selected. click Set Up Notifications. Select from the
following options:
SuiteScript FAQ
Applies to: SuiteScript 2.x | APIs | SuiteScript 1.0 | SuiteCloud Developer
■ General
■ SDF and SuiteApps
■ Code
■ Additional tools to work with along with SuiteScript
■ Errors
■ Logs
For FAQ information related to SOAP web services, see the help topic SOAP Web Services Frequently
Asked Questions (FAQ).
General
How often is the SuiteScript API documentation updated?
The SuiteScript API documentation is updated frequently and pushed to the NetSuite Help Center.
For the most current API documentation, see the help topic SuiteScript 2.x API Reference.
See the help topic SuiteScript Supported Records for information about supported records.
See the SuiteScript Records Browser for details related to SuiteScript-supported records.
See the SuiteScript Records Browser for details related to SuiteScript-supported sublists and their internal
IDs.
See the SuiteScript 1.0 to SuiteScript 2.x API Map for more details on the differences.
A new version of SuiteScript, SuiteScript 2.1, is also available. This version is the latest minor version of
SuiteScript. It extends SuiteScript 2.x by supporting additional ECMAScript language features and syntax.
For more information, see the help topic SuiteScript 2.1.
SuiteScript 1.0 isn't being updated with new features or enhancements. SuiteScript 1.0 scripts are still
supported, but for new or revised scripts, use SuiteScript 2.x to get the latest features and enhancements.
A new version of SuiteScript, SuiteScript 2.1, is also available. This version is the latest minor version of
SuiteScript. It extends SuiteScript 2.x by supporting additional ECMAScript language features and syntax.
For more information, see the help topic SuiteScript 2.1.
Also be aware that the system reads your library files in the order they appear on the Library Script File
tab on the Script record page. For example, if your first library file references the second library file, an
error will be thrown, since the first library file is loaded before the second.
If you're unsure about creating a Script record or loading library files, go to the topic Creating a Script
Record in the NetSuite Help Center.
See the help topic SuiteScript 2.x Standard and Dynamic Modes for more details.
What are the best practices when using Standard and Dynamic mode?
Standard mode is usually faster, so use it for read-only operations.
Dynamic mode may be needed when doing write operations of fields on which other field depend.
See the help topic SuiteScript 2.x Standard and Dynamic Modes for more details.
NetSuite uses a governance model to optimize performance, based on usage units. If you exceed the
allowed units, the script will be terminated.
Can a User Event script be used to trigger another User Event script?
Nested user event script execution is not supported.
See the help topic SuiteScript 2.x User Event Script Type for more details.
Does SuiteScript have a module that I can use to see information about my SuiteApp?
Yes, the N/suiteAppInfo module provides information about your SuiteApp, including whether a specific
SuiteApp is installed and a list of all SDF SuiteApps that are installed, along with the ID for the SDF
SuiteApp that contains a specific script (for multiple scripts specified). For more information about the N/
suiteappInfo module, see the help topic N/suiteAppInfo Module.
Code
How can I control the execution order of scripts deployed on a record?
To control script execution order, log in to NetSuite, go to Customization > Scripting > Scripted Records,
select your record type, and drag the scripts up or down
How many client and user event scripts can I deploy in a record?
You can deploy as many scripts as you need, but be aware that too many scripts deployed on single
record can cause performance issues.
How do I add a button in a User Event script that redirects to a Suitelet in SuiteScript 2.x?
In the beforeLoad callback, you get a form object on which any button can be added. That button can run
an arbitrary function. The function must use document.location =<url of a suitelet> for redirect.
See the help topic SuiteScript 2.x User Event Script Type or SuiteScript 2.x Suitelet Script Type for more
details.
See Creating Script Parameters Overview for more information about creating and working with script
parameters.
The endpoint you're connecting to must use a trusted CA, or the connection won't work. When
connecting to an endpoint from NetSuite, make sure it provides a full certification chain, including
intermediate certificates.
/**
* @NApiVersion 2.1
* @NScriptType Suitelet
*/
define(['N/ui/serverWidget', 'N/ui/message'], function(serverWidget, message){
function onRequest(context){
let form = serverWidget.createForm('Alert Form');
let msg = message.create({
type:message.Type.WARNING,
title:"Alert",
message: "Something occurred",
duration: 5000
});
form.addPageInitMessage(msg);
context.response.writePage(form);
}
return{
onRequest: onRequest
}
});
See the help topic Subrecord Scripting in SuiteScript 2.x Compared With 1.0 for more details.
See the help topic Record-Level and Form-Level Script Deployments for more details.
Scheduled scripts are server scripts that run sequentially on SuiteCloud Processors, whereas map/reduce
scripts run in parallel.
See the help topic SuiteScript 2.x Script Types for more details.
What does the script context seen in System Notes represent regarding the action on the
record?
The script context shows where the operation that changed the field came from -it's the second-most
nested scope in the stack of operations.
For example, if in the UI, the pageInit callback is used on a record to call nlapiRequestURL to trigger a
Suitelet. This calls another nlapiRequestURL to trigger a RESTlet, which loads a record that triggers a user
event that changes the field, then the context is RESTlet. The stack will be UI/Client/Suitelet/Restlet/
UserEvent. RESTlet is the second most nested scope.
scriptContext.newRecord stores the record which can be modified in the beforeSubmit callback, so you
can save it differently than what's shown in the UI. For example, you can override a memo before the
record is saved.
Errors
You can find SuiteScript error descriptions in SuiteAnswers. Type the error in the search box and click
Search.
How does “Record Has Been Changed” error get triggered in SuiteScript execution?
This error occurs when someone else (or another script) changes the record at the same time.
See the SuiteAnswers article Prevent losing data because of the error "Record has been changed" for
more details.
What is the “You do not have privileges to view this page” error message on the script
deployments page?
Users will get this error if any of the Select All box on the Audience tab on the Script Deployment page
isn't checked. This applies to both internal and external users, even those accessing the Suitelet without
logging in.
See the help topic Errors Related to the Available Without Login URL for more details.
What is the “You are not allowed to navigate directly to this page” error message when
accessing Suitelet?
Users will get this error if the Suitelet's Status isn't set to Released, even if they're accessing it externally.
See the help topic Errors Related to the Available Without Login URL for more details.
For more information about usage limits, see the help topic SuiteScript Governance and Limits
Keep an eye on your script usage, as there are limits in place. For more information, see Monitoring Script
Usage.
For more information about usage limits, see the help topic SuiteScript Governance and Limits
See the SuiteAnswers article SuiteScript Error SSS_INVALID_SUBLIST_OPERATION for more details.
Logs
How long will the script execution logs be available on my account?
You can find script execution logs in two places:
■ Execution Log tab on Script and Script Deployment records — Shares log storage with other
customers on the same database. To prevent excessive logging, there's a storage limit for script
execution logs on each NetSuite database instance. If the log storage limit is reached on a server, all
logs for all customers on that server will be deleted. You might have logs older than 30 days if the
volume is low, but if it's high, you might only have logs from the past week. To keep important log
information, consider storing it in custom records.
■ Script Execution Log page — The execution logs at Customization > Scripting > Script Execution
Logs stores logs for up to 30 days, no matter how many logs there are. This page can only show up to
10,000 log results at a time. If you have more than 10,000 logs, you can filter the page to see the ones
you need. Use the Filters section at the top of the pagee to narrow down the logs by date, script, or
log level. Keep in mind that you can't do a full search or customize the view on this page.