# Fix NetSuite RCRD_HAS_BEEN_CHANGED Error

> Source: https://netray.co/erp-help/netsuite-rcrd-has-been-changed-error
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

RCRD_HAS_BEEN_CHANGED, shown to users as a message that the record was changed by another user or in another window, fires when NetSuite's optimistic concurrency check detects that the record's last-modified stamp changed between when it was loaded and when the save was submitted. Fix it by identifying the concurrent writer, whether a user, a workflow, or a script, and serializing the conflicting updates instead of both racing to save the same record.

## Kind

error

## System

netsuite

## Erp

Oracle NetSuite

## Module

Record Concurrency / SuiteScript

## Query

The record you are trying to edit has been changed by another user NetSuite

## Alternate Queries

- RCRD_HAS_BEEN_CHANGED NetSuite error
- NetSuite record has been changed by another user or in another window
- NetSuite concurrent edit conflict SuiteScript

## Applies To

NetSuite UI record editing and SuiteScript 1.0/2.x record.save(), all record types

## Steps

### How to fix RCRD_HAS_BEEN_CHANGED

**Items:**

In the UI, the fix is simply to refresh the record and reapply your edit; the error itself is NetSuite protecting you from overwriting someone else's save.

In SuiteScript, check whether the same record is being loaded and saved by more than one script (a User Event and a Scheduled Script, or two Map/Reduce reduce keys) at nearly the same time.

Search Customization > Scripting > Script Deployments for every script deployed on the record type in question and check which ones run on the same trigger, since simultaneous afterSubmit executions on one record are the most frequent self-inflicted cause.

If two of your own scripts are colliding, consolidate the logic into a single script or use the Execution Context and Sequence fields on the deployment record to control order.

For Map/Reduce jobs that update a shared parent record from multiple reduce keys, reduce the granularity so only one reduce invocation touches a given parent record, or add retry logic with record.load() immediately before each save.

Add try/catch around record.save() with a short retry (reload, reapply the one field you need, save again) for scripts that legitimately may race with user edits, capped at two or three attempts to avoid infinite loops.

For integration-driven high-frequency updates, such as a webhook updating order status, queue updates to the same record instead of firing them concurrently from multiple threads.

## Sections

### What optimistic concurrency means here

**Body:**

NetSuite does not lock records for editing the way some legacy client-server ERPs do. Instead it uses optimistic concurrency: when a record is loaded, NetSuite notes its last-modified state, and when a save is submitted it checks that state has not changed since. If it has, the save is rejected with RCRD_HAS_BEEN_CHANGED rather than silently overwriting the other change.

This is a safety feature, not a bug, but it becomes a real operational problem when it fires between two automated processes that should never conflict in the first place, for example a nightly integration and a Scheduled Script both trying to update the same batch of records.

### Diagnosing script-versus-script races

**Body:**

The most common source in scripted environments is two afterSubmit User Event scripts on the same record type, both loading and saving the record independently in response to the same edit. Because both start from the pre-edit state, whichever saves second gets RCRD_HAS_BEEN_CHANGED against the first script's save.

List every script deployment on the record type (Customization > Scripting > Script Deployments, filter by record type) and check the Execution Context and event type columns for overlaps. Consolidating two afterSubmit scripts that both call record.load() plus save() into a single script that makes both changes in one save eliminates the race entirely.

### Handling legitimate concurrent access

**Body:**

When the conflict is between a genuine user edit and a background process, not two of your own scripts, the correct fix is not to force the save through but to retry against the freshest version of the record. Load the record again immediately before the retry, reapply only the specific field your process needs to change, and save.

Cap retries at two or three attempts with a short delay, and log a warning rather than silently swallowing the failure after max retries, since repeated collisions usually indicate a design issue, too many processes touching one record, rather than bad luck.

**Code:**

var attempts = 0;
while (attempts < 3) {
  try {
    var rec = record.load({ type: type, id: id });
    rec.setValue({ fieldId: 'custbody_status', value: 'done' });
    rec.save();
    break;
  } catch (e) {
    if (e.name !== 'RCRD_HAS_BEEN_CHANGED') { throw e; }
    attempts++;
  }
}

## Pitfalls

- Two of your own afterSubmit scripts both loading and saving the same record independently instead of consolidating logic into one script.
- Map/Reduce jobs where multiple reduce invocations update the same parent record concurrently.
- Integration webhooks firing updates to the same record in parallel instead of queued or serialized.
- Retrying a save in a loop without reloading the record first, which just repeats the same collision.
- Treating this as a random glitch instead of tracing the actual concurrent writer, which almost always exists and is findable.

## Ai Angle

Grounded on your script deployment configuration, ERPray can list every script and workflow action attached to a record type and flag the ones most likely to race against each other on the same trigger, which is the manual detective work this error usually requires. For recurring conflicts on specific record types, you can ask it to summarize which processes touched a given record in the minutes before a failed save, using your account's system notes as grounding.

## Faq

### Does this mean I lost my data when I see this error?

**Answer:** No, NetSuite blocks the save specifically to prevent silent data loss. Your edit was never committed; you need to refresh to the current version of the record and reapply your change.

### Can I disable this concurrency check?

**Answer:** No, there is no supported way to disable NetSuite's optimistic concurrency check; it is a platform-level protection. The correct approach is to eliminate or serialize the actual conflicting writers.

### Why does this happen more often on Map/Reduce jobs?

**Answer:** Because Map/Reduce distributes work across parallel reduce invocations. If your reduce function's key grouping allows two invocations to both update the same parent or related record, they race against each other exactly like two independent scripts would.

### Is this related to record locking permissions?

**Answer:** No, it is unrelated to role permissions or record locking settings. It is purely a timestamp-based concurrency check that fires regardless of what role or script is doing the saving.

## Search terms

RCRD_HAS_BEEN_CHANGED NetSuite, NetSuite record changed by another user error, NetSuite concurrent edit conflict, NetSuite Map/Reduce record collision, NetSuite record.save error fix, NetSuite optimistic concurrency, NetSuite afterSubmit script race condition, NetSuite refresh record error

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
