Last updated on June 13, 2024.
- Aug 20, 2023: Updated logic to detect system users based in entity type rather than email to cover a rare but technically possible edge case pointed out by Elie Ciment.
Are you grappling with accurately pinpointing NetSuite system users? A system user is a fixed entity that remains unalterable within the application. If you’ve landed here due to encountering an error message like "Invalid Field Value -4 for the following field: xxx"
or "Invalid xxx reference key -4"
in a script or workflow that assigns a user to an employee or entity field on a record, this article will explain the proper way to identify a system user. We’ll also explore why the conventional approach of assuming all negative IDs are system users falls short.
Table of Contents
TL;DR
- NetSuite lacks a standard method to determine if the current user is a system user.
- Trying to set a system user in a field expecting a user, such as an entity or employee field, triggers an error.
- The common assumption that all negative internal IDs signify system users is flawed.
- Using a straightforward lookup function (script), we can more accurately detect system users.
Use Case for Exclusion of NetSuite System Users
Understanding the relevance of system users is crucial before delving into the solution. For instance, you might want to display the creator of a transaction in the header section for easier access. While this information is accessible via the system notes, a custom transaction body field of type Entity or Employee could enhance accessibility. Such a field can be populated via a workflow or script upon creating a transaction.
This will work fine in most cases. However, for transactions created by background processes e.g. Scheduled or Map/Reduce script, the user will be -System-
and attempting to set that user’s ID in your field will produce an error like Invalid Field Value -4 for the following field: custbody_xxx
. To prevent this error, you need to identify and exclude the system user.
Interesting Insights About NetSuite System Users
Given NetSuite’s absence of a standard detection method for system users, I did some testing which revealed intriguing findings.
I ran the following lookup in the browser console in multiple NetSuite accounts to investigate entities with the first 10 negative internal IDs:
require(['N/search'], function(search) {
try {
console.log('In');
lookupEntity(-1);
lookupEntity(-2);
lookupEntity(-3);
lookupEntity(-4);
lookupEntity(-5);
lookupEntity(-6);
lookupEntity(-7);
lookupEntity(-8);
lookupEntity(-9);
lookupEntity(-10);
console.log('Out');
} catch (error) {
console.error('Error', error);
}
function lookupEntity(id) {
let lookupResults = search.lookupFields({
id: id,
type: 'entity',
columns: [
'internalid',
'isinactive',
'email',
'entityid',
'type'
]
})
console.log(`Lookup entity ID ${id}`, JSON.stringify(lookupResults));
}
})
The results are interesting:
Internal ID | Is Inactive | Entity ID | Type | |
---|---|---|---|---|
-2 | False | -No Company- | Company | |
-3 | False | -Accountant- | Vendor | |
-4 | False | -System- | Internal | |
-5 | False | jo*****@co*****.com | John Doe | Employee |
-1, -6, -7. -8, -9, -10 | N/A | N/A | N/A | N/A |
A few observations:
- Multiple active system users are automatically created during NetSuite account provisioning. The creation date of all these users corresponds to the day the NetSuite account was provisioned.
- Interestingly, internal ID
-1
and <-5
are not used. Additionally, only-System-
appears to be visible in the UI. It’s unclear to me what-No Company
and-Accountant-
are used for. - The user with internal ID
-5
is an actual user! In fact, this is the user in whose name the account was provisioned i.e. the very first user. Notice that, unlike the other users, this user has type ‘Employee’. - Among the users with negative internal IDs, only the real user has an email address assigned.
- Although these users are active (
isinactive = false
),record.load()
fails with aRCRD_DSNT_EXIST
error code and message:That record does not exist. Invalid record: employeeId = xxx
. Similarly, attempting to useurl.resolveRecord()
on these entities will result inRCRD_DSNT_EXIST
.
Solution
Building upon these insights, I came up with the following solution (SS 2.1):
function isSystemUser(id) {
let systemUser = false;
if (id < 0) {
const lookupResults = search.lookupFields({ id: id, type: 'entity', columns: 'type' });
if (Array.isArray(lookupResults.type)) {
systemUser = lookupResults.type[0]?.value !== 'Employee';
}
}
return systemUser;
}
This solution detects system users by checking the entity type. Only valid users with a negative internal ID and type different from “Employee” are considered system users. Running this function against our reference internal IDs, the results are satisfactory:
Internal ID | isSystemUser() | Type |
---|---|---|
-2 | True | Company |
-3 | True | Vendor |
-4 | True | Internal |
-5 | False | Employee |
-1, -6, -7. -8, -9, -10 | False (non-existent internal IDs are by implication not system users) | N/A |
Conclusion
This article clarifies the intricate nature of NetSuite’s system user accounts and how to accurately identify and handle them. While the reasons behind the existence of multiple system accounts remain undisclosed, we can make informed assumptions based on observed patterns.
NetSuite Insights is on a mission to raise the standards around NetSuite practices, one insight at a time. If that resonates with you, learn how you can become an author/collaborator here.
Don’t miss a beat – subscribe to our no-nonsense email list to have these game-changing insights hit your inbox as soon as they’re published. Ignorance? Nah, you’ve got a smarter option. Choose wisdom, choose insights!
-3 is the free accountant login that NS used to give away years ago for free. Now the accountant has to be enrolled in the NS Accountant program in NS order to get a free login to client’s account.
Interesting. Thanks for your insights, Nick.