← All posts
SuiteScriptTechnical DebtAuditGovernance

The SuiteScript Technical Debt Audit: A Practical Process

Ryzoa··11 min read

The SuiteScript Technical Debt Audit: A Practical Process

Most organisations running NetSuite for more than a few years have a customisation estate they cannot fully describe. The original implementation partner is gone. The internal admin who built half the scripts left two years ago. There is a folder in the File Cabinet called Old Scripts - DO NOT DELETE with 40 JavaScript files and nobody knows which ones are still in use.

When a senior person asks "are we confident our customisations will survive the next upgrade?" the honest answer is usually "we don't know." A SuiteScript audit is how you find out.

This post describes a process you can follow yourself, or most of it. I will be honest about the points where it becomes genuinely difficult without deep SuiteScript experience, because the point of describing the process is not to make you think you don't need help. It is so you can make an informed decision about where you need it.

Section 1: Building the Script Inventory

The starting point is a complete list of what is actually deployed and running in your account.

The Script List. Go to Setup > Customization > Scripting > Scripts. This page shows every script record in your account. Export the list to CSV. There is no native export, but you can use a saved search on the Script record type. The fields you want are:

  • Script Name
  • Script ID (customscript_...)
  • Script Type (User Event, Client, Scheduled, RESTlet, Map/Reduce, Suitelet, etc.)
  • SuiteScript Version (1.0 or 2.0/2.1)
  • Record Types (for User Event and Client scripts)
  • Last Modified Date
  • Created Date

The Deployment List. Each script can have multiple deployments. A deployment is the association between a script and a specific record type or trigger, with status (Released, Testing, Not Scheduled) and run-order settings. Go to Setup > Customization > Scripting > Script Deployments. The critical column here is Status: a deployment in "Not Scheduled" or "Testing" status is either dormant or only running for administrators. It is still sitting in your account as part of the customisation surface, but it is not running for regular users.

What the Script List does not tell you. This is important: the Script List shows you what is deployed, not what is actually doing something meaningful. A script with Status = Released may be running on every Sales Order save and producing no observable effect, because the business logic it implements is now redundant (handled by a workflow, a standard NetSuite feature, or simply no longer needed). Conversely, a script with Status = Testing may be the only thing preventing a critical data integrity problem from affecting your administrators.

You cannot assess actual business impact from the Script List alone. That requires tracing what each script does.

Building the inventory. For each script, add columns to your spreadsheet:

  • What does it do? (One sentence, based on reading the code)
  • What record type(s) does it affect?
  • What is the business process it supports?
  • Who owns it? (Which team or process depends on it)
  • Is the owner aware it exists?

The last question sounds absurd, but in my experience doing these audits, around 20-30% of scripts in a mature account are unknown to the current business stakeholders. They were built for a project that was later abandoned, or for a user who left, or for a workflow that was superseded. These are prime retirement candidates.

Section 2: Risk Scoring

Once you have the inventory, you score each script on two dimensions: upgrade risk and business impact.

Upgrade Risk

Score from 1 (low) to 5 (high) based on:

SuiteScript version. 1.0 scripts score higher than 2.1 scripts. A 1.0 Client Script scores 5 out of 5 on upgrade risk; it is a question of when it will break, not if. A well-written 2.1 script with no hardcoded IDs and proper module boundaries scores 1.

Use of deprecated patterns. Grep the file for:

  • nlapiLoadRecord, nlapiGetFieldValue, nlapiSetFieldValue, nlapiSearchRecord, nlapiRequestURL, nlapiScheduleScript, nlapiCreateRecord, nlapiSubmitField, nlapiSubmitRecord: any of these in a 2.x file scores 4+.
  • Hardcoded numeric values used as field values (potential internal IDs): score 3+.
  • isDynamic: true without accompanying justification in a comment: score 2+.

Governance assumptions. Look at scripts that iterate over search results without using Map/Reduce. Count the record.load() and record.submitFields() calls in any loop, at roughly 10 units each on transactions. A User Event script has 1,000 governance units to spend and a Scheduled Script has 10,000, so any loop whose record count is driven by data volume rather than a fixed bound will eventually hit the ceiling. Data volumes only grow.

Last modified date. A script that has not been touched in 3+ years may be written against APIs that have since changed. Age is a proxy for accumulated risk.

Business Impact

Score from 1 (low) to 5 (high) based on:

What breaks if this script stops running? Categorise the failure mode: cosmetic (a label doesn't auto-populate), operational (a document doesn't auto-generate), financial (a calculation is wrong), or critical (data integrity is compromised, transactions cannot be saved).

How quickly would it be noticed? A script that runs on Sales Order save will have its failure noticed within hours. A monthly Scheduled Script that generates a report might not be noticed for 30 days.

How many users or transactions are affected? A script on Customer (affects every customer record) scores higher than a script on a custom record type used by one department.

Is there a manual workaround? If the script fails and there is a reasonable manual process to cover it while it is fixed, business impact is lower. If there is no workaround and the data simply doesn't flow until the script is fixed, impact is high.

The Risk Matrix

Plot each script on a 5x5 grid with upgrade risk on one axis and business impact on the other. The quadrants map to actions:

  • High risk + High impact (top-right): Immediate remediation. These scripts will break and the business will notice. They need to be at the front of your migration queue.
  • High risk + Low impact (top-left): Schedule for retirement or low-priority migration. These will break but it won't matter much.
  • Low risk + High impact (bottom-right): Monitor and protect. These are your most valuable scripts. Review them before every upgrade. Document them thoroughly.
  • Low risk + Low impact (bottom-left): Leave them. Review at your next audit cycle.

Section 3: Common Findings and What They Mean

After doing several of these audits, the same patterns come up repeatedly. Here is what they mean when you find them.

"Half our scripts are SuiteScript 1.0." This is common in accounts that went live before 2018 and haven't had a major re-implementation. The risk is proportional to the script types involved. 1.0 Scheduled Scripts are less immediately dangerous than 1.0 Client Scripts, because they run server-side and don't have the UI timing problem. But they are all on borrowed time.

"We have scripts with no owner and no documentation." This is a data integrity risk as well as a maintenance risk. Scripts without documentation may be enforcing business rules that are not written down anywhere. If the script disappears (deleted, broken, accidentally de-deployed), that rule disappears with it and nobody knows why the data suddenly looks different.

"Several scripts have the same last modified date." This usually means they were all imported as part of a bundle or package, and were last updated when the bundle was last updated. Check when the bundle was last released. If it was 2021 and the account has upgraded several times since, that bundle's scripts may be out of date.

"We have scripts that reference internal IDs that don't match between sandbox and production." You will only find this by comparing values: looking up the internal IDs in both environments and seeing whether they match. This is the silent killer: the script runs without errors in sandbox, but sets the wrong values in production, and nobody realises because the field just shows "Option 3" in both environments.

"The File Cabinet has JavaScript files that are not referenced by any script record." These are orphaned files. They may be backups, may be scripts that were deleted at the script record level but not in the File Cabinet, or may be files deployed by a tool that manages script records separately. They are not causing harm, but they create confusion. Clean them up.

"We have RESTlets with no documentation on what calls them." This is a security audit risk as much as a technical one. An undocumented RESTlet is an API endpoint in your production environment that you cannot account for. Find out what calls it, document the integration, and verify the TBA credentials are properly managed.

Section 4: What to Do with the Results

The audit produces a prioritised remediation list. The actions are:

Retire. Delete scripts that have no business impact and no active deployment (or where the deployment can safely be deactivated). Document what was removed and why. This is the easiest win: it reduces your maintenance surface without requiring any development work.

Migrate. Scripts in the high risk/high impact quadrant need proper SuiteScript 2.1 rewrites. This is development work that requires understanding both the existing logic and the correct 2.1 approach. The migration is also an opportunity to fix the underlying patterns (governance, ID hardcoding, and so on) that created the risk in the first place.

Document. For scripts in the low risk/high impact quadrant, write documentation now, while you can still trace the logic. What does it do? Why does it exist? What breaks if it stops? Who to contact? Store this documentation somewhere it will be found: in a system of record that survives staff turnover, rather than in a comment in the script file that nobody reads.

Monitor. For everything else, create a recurring review process. Before each NetSuite upgrade preview period, run through the risk matrix again. Check NetSuite's release notes for deprecated APIs. Identify any scripts that reference them.

A Realistic Expectation

You can do most of this process yourself: the inventory, the basic risk scoring, identifying the orphaned files and the undocumented RESTlets. A technically capable NetSuite administrator can build the spreadsheet and identify the obvious high-risk scripts.

Where it gets genuinely difficult is the code-level assessment: understanding what a script is actually doing, identifying subtle anti-patterns (the isDynamic bug, the governance loop problem, the internal ID mismatches), and making correct migration decisions for the complex scripts. That requires writing SuiteScript at a level that goes beyond administration into development.

The organisations that benefit most from bringing in a specialist are those where the audit reveals a significant body of high-risk, high-impact scripts, the ones where the stakes of getting the migration wrong are real. If your audit produces a short list of simple scripts, you may be able to handle the remediation internally. If it produces 30 scripts in the top-right quadrant, that is a different situation.

Either way, knowing what you have is better than not knowing.


If you want to run this process but want a specialist to work through the code-level assessment with you, or to own the remediation for the high-risk scripts, that is the SuiteScript audit service I offer. You come away with a full inventory, a prioritised risk register, and a clear plan.

Frequently asked questions

How do I find all the SuiteScript deployed in my NetSuite account?

Go to Customization > Scripting > Scripts. This lists every script record in the account. Filter by Script Type to separate Client Scripts, Scheduled Scripts, RESTlets, and so on. For each script, check the Deployments tab to see which record types it runs on and whether the deployment status is Released or Testing. Export the list. A mature account can have 50 to 200 scripts; the inventory step is usually slower than expected.

What does a SuiteScript technical debt audit typically find?

The most common findings are orphaned scripts deployed to record types that are no longer in use, SuiteScript 1.0 scripts with upgrade risk from timing dependencies on the Responsive UI, governance limit assumptions in Scheduled Scripts that will silently fail as data volume grows, hardcoded internal IDs that behave differently in sandbox and production, and RESTlets with no documentation of what calls them. Most implementations have at least a handful of each category.

How do I decide which SuiteScript to migrate versus which to retire?

Score each script on two axes: how likely is it to break in the next upgrade, and how bad is it if it does? High risk and high business impact means it needs a proper SuiteScript 2.1 rewrite. High risk and low impact means it can usually be retired and deleted, which reduces your maintenance surface without requiring any development. Low risk and high impact means it needs documentation and a monitoring plan while you queue the migration. Low risk and low impact: leave it, add it to the watch list.

When should I run a SuiteScript technical debt audit?

Before each NetSuite upgrade preview window, so you can identify risky customisations before they break in production rather than after. Also immediately after inheriting an implementation from a previous partner — you need to know what you have before you can know what you are responsible for. For accounts that have been running for five or more years without a systematic review, the audit almost always uncovers something that would have caused a problem in the next upgrade cycle.

Have a specific problem in mind?

A 30-minute technical review call to understand what's in your codebase and whether this is the right fit.

Book a technical review