RCRD_DSNT_EXIST — what it means and how to fix it
RCRD_DSNT_EXIST: It means a SuiteScript, integration or URL asked NetSuite to load a record by internal ID and type, and no record matches that combination. Usually the internal ID is wrong, was deleted, belongs to a different record type, or comes from another account — internal IDs are not the same across sandbox and production.
When do you see RCRD_DSNT_EXIST?
- A SuiteScript fails on record.load or record.transform with RCRD_DSNT_EXIST, even though the record looks like it exists in the UI.
- A saved search, workflow or integration references an internal ID that was deleted or was never created.
- A script that works in sandbox throws RCRD_DSNT_EXIST in production (or vice versa) because an internal ID was copied between accounts.
What causes RCRD_DSNT_EXIST?
- The internal ID passed to record.load (or lookupFields/submitFields) does not exist — a typo, a hard-coded ID, or a record that was deleted after the ID was captured.
- The record type doesn't match the ID — loading internal ID 123 as 'invoice' when 123 is actually a 'salesorder' throws RCRD_DSNT_EXIST: the ID exists, but not for that record type.
- The internal ID comes from a different account — internal IDs are account-specific, so an ID that is valid in sandbox is meaningless in production and throws when the same code runs there.
- An integration or CSV import references a record by an internal ID (or a transform source) that hasn't been created yet, so the lookup runs before the record exists.
How do I fix RCRD_DSNT_EXIST?
Prove the record exists, confirm you're asking for it by the right type in the right account, then make the code fail gracefully when it genuinely isn't there.
- Open the record directly in the UI to confirm it exists and wasn't deleted — go to the record type's list and search for the internal ID, or load it from the URL. If it isn't there, the ID is the problem, not the script.
- Check the record type matches the ID. record.load needs the type the ID actually belongs to; confirm it with a search rather than assuming, then load with the correct record.Type.
var rec = record.load({ type: record.Type.SALES_ORDER, // must match what id 123 actually is id: 123 }); - Confirm you're in the right account — internal IDs are not portable between sandbox and production. Re-look-up the ID in the target account instead of reusing one captured from another environment.
- For integrations and CSV, reference records by a stable external ID, or ensure the referenced record is created before it is referenced — never hard-code internal IDs that vary by account.
- Make the code defensive: wrap record.load in try/catch and handle the missing-record case, or use search.lookupFields, which returns an empty result instead of throwing when a record may legitimately be absent.
try { var rec = record.load({ type: recType, id: recId }); } catch (e) { if (e.name === 'RCRD_DSNT_EXIST') { // handle the missing record } else { throw e; } }
How do I stop it happening again?
- Never hard-code internal IDs that differ between accounts — look them up by external ID, name or a saved search at run time.
- Treat sandbox and production internal IDs as separate namespaces; re-fetch IDs after a refresh rather than copying them between environments.
- Pass the record type the ID actually belongs to, and verify it with a search before a blind record.load.
- Wrap record loads that might miss in try/catch (or use lookupFields) so a deleted or absent record is handled, not fatal.
SuiteScript version note: RCRD_DSNT_EXIST is raised identically in SuiteScript 2.0 and 2.1 (as an error whose name is 'RCRD_DSNT_EXIST'); SuiteScript 1.0 surfaced the same condition through nlapiLoadRecord. The diagnosis — verify existence, then type, then account — is the same across versions.
Frequently asked questions
- The record is right there in the UI — why does the script say it doesn't exist?
- Almost always a type or account mismatch: the internal ID belongs to a different record type than the one you passed to record.load, or it's an ID from another account (sandbox versus production). The record exists — just not for the type-and-account combination you asked for.
- Is RCRD_DSNT_EXIST the same as a permission error?
- No. RCRD_DSNT_EXIST means no matching record was found for that ID and type. If the record exists but your role or subsidiary can't see it, NetSuite usually raises INSUFFICIENT_PERMISSION instead.
- Why does my script work in sandbox but fail in production?
- Internal IDs are account-specific. An ID created in sandbox has no meaning in production, so a hard-coded ID throws RCRD_DSNT_EXIST after the code is moved. Look the record up at run time instead of hard-coding the ID.
Updated · Reviewed by Wouter Nortje, CA