VERSICH

NetSuite Sublist Mandatory Field Checks That Survive Imports

netsuite sublist mandatory field checks that survive imports

NetSuite Sublist Mandatory Field Checks That Survive Imports

Making a NetSuite sublist field mandatory with SuiteScript requires more than changing the field display on a form. A `beforeLoad` User Event can mark a sublist field as required for users entering data through the NetSuite interface, but that setting does not provide complete protection against CSV imports, web services, RESTlets, or other automated processes. For reliable enforcement, we combine a user interface rule with server-side validation in a `beforeSubmit` script. A Client Script can also provide immediate line-level feedback while the user edits the record.

This distinction matters because a NetSuite transaction is made up of a body and one or more sublists. A value that appears required on the Sales Order item sublist still needs to be checked independently for every line before the record is saved.

What does a mandatory NetSuite sublist field actually require?

A mandatory NetSuite sublist field requires a valid value on every applicable sublist line before the record can be saved. For example, if every item line on a Sales Order must include a custom project reference, the validation needs to inspect each line rather than checking only the body-level record.

There are three separate parts to a reliable implementation:

  1. Form behavior: The field appears mandatory to users working in the NetSuite UI.

  2. Line-entry behavior: Users receive feedback while adding or editing a sublist line.

  3. Server-side enforcement: The record is rejected if any required line value is missing, regardless of how the record enters NetSuite.

The first layer is useful, but it is not enough on its own. A form-level mandatory flag improves usability. It does not replace record validation.

This is the core answer to the question of how to make a NetSuite sublist field mandatory: use `serverWidget` in a `beforeLoad` User Event to mark the field as mandatory on the form, then use `N/record` in `beforeSubmit` to loop through the relevant sublist and throw an error when a required value is missing.

How do you set a NetSuite sublist field to mandatory in SuiteScript?

Use a `beforeLoad` User Event and set the target sublist field’s `isMandatory` property to `true`. The field must be accessed through the sublist object, not through the body-level form fields.

Here is a SuiteScript 2.1 example for a custom field named `custcol_project_reference` on the item sublist:

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
define(['N/ui/serverWidget'], (serverWidget) => {
    function beforeLoad(context) {
        if (
            context.type !== context.UserEventType.CREATE &&
            context.type !== context.UserEventType.EDIT &&
            context.type !== context.UserEventType.COPY
        ) {
            return;
        }

        const form = context.form;
        const itemSublist = form.getSublist({
            id: 'item'
        });

        if (!itemSublist) {
            return;
        }

        const projectReferenceField = itemSublist.getField({
            id: 'custcol_project_reference'
        });

        if (projectReferenceField) {
            projectReferenceField.isMandatory = true;
        }
    }

    return {
        beforeLoad
    };
});

The important mechanism is `form.getSublist()`, followed by `sublist.getField()`. A sublist field is not retrieved in the same way as a body field. The field ID also needs to be the internal ID used by the sublist, such as `custcol_project_reference` for a transaction column field.

The `CREATE`, `EDIT`, and `COPY` checks prevent the rule from being applied unnecessarily to view or print pages. We also recommend testing the script against every record type and form where the sublist exists. A field that appears on one custom transaction form might not be present on another.

What this UI setting does not cover

Setting `isMandatory` changes the form presented to the user. It does not guarantee that every record entering NetSuite contains the required value.

Records can be created or updated through channels that do not use the same browser form, including:

  • CSV imports

  • SOAP web services

  • REST web services

  • RESTlets

  • scheduled scripts

  • Map/Reduce scripts

  • integrations and middleware

For that reason, the `beforeLoad` script should be treated as the user experience layer. The enforcement layer belongs in `beforeSubmit`.

How do you validate every sublist line before saving?

Use a `beforeSubmit` User Event to read the sublist line count, retrieve the target field on each line, and throw a controlled error when a required value is absent.

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
define(['N/error'], (error) => {
    function beforeSubmit(context) {
        if (
            context.type !== context.UserEventType.CREATE &&
            context.type !== context.UserEventType.EDIT &&
            context.type !== context.UserEventType.COPY
        ) {
            return;
        }

        const newRecord = context.newRecord;
        const sublistId = 'item';
        const fieldId = 'custcol_project_reference';
        const lineCount = newRecord.getLineCount({
            sublistId
        });

        for (let line = 0; line < lineCount; line += 1) {
            const value = newRecord.getSublistValue({
                sublistId,
                fieldId,
                line
            });

            if (value === null || value === undefined || String(value).trim() === '') {
                throw error.create({
                    name: 'MISSING_SUBLIST_VALUE',
                    message: `Line ${line + 1} requires a project reference.`,
                    notifyOff: false
                });
            }
        }
    }

    return {
        beforeSubmit
    };
});

This script validates the record immediately before NetSuite commits it. The internal line index starts at zero, so the message uses `line + 1` to show a human-readable line number.

The check deliberately handles `null`, `undefined`, and blank strings. That is important because different record sources can represent an empty value differently. A simple condition such as `if (!value)` can also incorrectly reject valid values such as numeric zero, so an explicit empty-value check is safer.

Skip lines that are not applicable

Not every sublist line necessarily requires the same field. If the requirement applies only to inventory items, certain item categories, or lines with a particular checkbox selected, add a condition before validating the target field.

const itemType = newRecord.getSublistValue({
    sublistId: 'item',
    fieldId: 'itemtype',
    line
});

if (itemType === 'Service') {
    continue;
}

const value = newRecord.getSublistValue({
    sublistId: 'item',
    fieldId: 'custcol_project_reference',
    line
});

The exact field available for identifying a line depends on the record type and sublist. Test the internal ID in the target account rather than assuming that a field exposed in the UI has the same availability in every execution context.

Should you use a Client Script for immediate validation?

Use a Client Script when users need feedback as soon as they commit a line, but do not rely on it as the only control. The `validateLine` entry point is appropriate for checking a sublist line before it is added or committed in the browser.

/**
 * @NApiVersion 2.1
 * @NScriptType ClientScript
 */
define(['N/ui/dialog'], (dialog) => {
    function validateLine(context) {
        if (context.sublistId !== 'item') {
            return true;
        }

        const currentRecord = context.currentRecord;
        const value = currentRecord.getCurrentSublistValue({
            sublistId: 'item',
            fieldId: 'custcol_project_reference'
        });

        if (value === null || value === undefined || String(value).trim() === '') {
            dialog.alert({
                title: 'Required field',
                message: 'Enter a project reference before committing this line.'
            });

            return false;
        }

        return true;
    }

    return {
        validateLine
    };
});

`getCurrentSublistValue()` is the correct method when the user is editing the current unsaved line. It is different from `getSublistValue()`, which reads an existing line by index from the record object.

A Client Script improves the interaction because the user sees the problem at line entry rather than after clicking Save. However, browser scripts do not run for every integration or server-side process. The `beforeSubmit` check remains essential.

A practical implementation therefore uses:

LayerSuiteScript mechanismMain purpose
Form presentation`beforeLoad`, `serverWidget`Show the field as mandatory in the UI
Line entryClient Script, `validateLine`Give immediate feedback while editing
Record enforcement`beforeSubmit`, `N/record`Reject incomplete records from all supported entry paths

What is the difference between a mandatory field and a validated field?

A mandatory field is a form configuration, while a validated field is a business rule enforced when the record is submitted. In NetSuite, confusing the two creates a common data-quality gap.

A mandatory display setting tells the browser to expect a value. A server-side validation script evaluates the actual record payload. This distinction becomes especially important when an integration creates a transaction without loading the standard NetSuite form.

The difference also affects error handling. A form-level mandatory rule might show a generic message near the field. A `beforeSubmit` User Event can provide a business-specific message, identify the line number, and apply conditional logic based on subsidiary, transaction status, item type, or another field.

For example, a requirement might be:

  • Every item line requires a project reference.

  • Lines for non-billable items are exempt.

  • Closed transactions should not be revalidated during a status-only update.

  • The rule applies only to one subsidiary.

Those requirements are not adequately expressed by `isMandatory = true`. They belong in explicit validation logic.

How should you handle edits, copies, and integrations?

Start by defining when the rule applies, then encode that decision in the User Event. A mandatory sublist value may be required on creation but not during every subsequent edit.

For example, validating all historical records during a minor edit can block legitimate maintenance work if old lines were created before the rule existed. On the other hand, skipping validation on edits could allow users to remove a previously valid value.

The correct behavior depends on the business requirement. Consider these questions:

  • Does the field need to be present on every new record?

  • Should existing incomplete records be repaired before enforcement begins?

  • Can a user remove the value during an edit?

  • Does the rule apply to copied transactions?

  • Should integrations receive a clear error when they omit the field?

  • Does the requirement change by subsidiary, form, status, or transaction type?

A copied transaction deserves specific attention. If the source record contains a valid column value, the copied line might already pass validation. If the field is not copied because of field sourcing or transaction configuration, the new record should fail clearly rather than saving with an incomplete line.

For integrations, return messages that identify the missing field and line number. Integration teams can then correct the payload without searching through a generic “unexpected error” response. If the validation is conditional, include the condition in the message only when it helps the sending system correct its data.

When is a workflow better than SuiteScript?

A workflow is appropriate when the requirement is simple, visible to administrators, and supported by workflow conditions. SuiteScript is the stronger choice when the logic requires line iteration, integration enforcement, complex conditions, or a precise error message.

A workflow can set values, display messages, route approvals, or prevent a transition based on record conditions. It is useful for straightforward processes that administrators need to maintain without editing code. We cover the broader use of NetSuite workflows for automated field population separately.

For a sublist mandatory rule, the deciding factor is whether the workflow can reliably inspect every relevant line and stop the save in all required contexts. If the requirement is “the field must be populated on every item line, including records received through integrations,” a `beforeSubmit` User Event provides more direct control.

We recommend choosing SuiteScript when:

  • The validation must run for non-UI record creation.

  • The rule loops through multiple sublist lines.

  • Different line types have different requirements.

  • The error must identify the exact missing line.

  • The validation must account for execution context or transaction status.

We recommend a workflow when the requirement is limited to a simple record-level condition and the workflow behavior has been tested against the intended entry channels.

Common SuiteScript mistakes when making a sublist field mandatory

The most common mistake is validating only the current line. A record can contain many lines, and the script must inspect each applicable line before saving.

Another mistake is using a body-field method for a column field. `getValue()` reads body fields. For a sublist line, use `getSublistValue()` in a User Event or `getCurrentSublistValue()` in a Client Script.

Do not assume that the UI mandatory flag protects imports. Always test the rule through at least one non-UI path that matters to the account. CSV imports are particularly useful because they expose whether the server-side validation runs as expected and whether the resulting error is understandable to the person managing the import.

Also avoid hard-coding a rule without considering deletes. If a user deletes a line that contained the required value, the remaining lines still need validation. `getLineCount()` should be evaluated from the final submitted record, not from an earlier state.

Finally, avoid attaching multiple scripts that enforce the same requirement with different messages. Duplicate validation creates confusing behavior and makes future maintenance harder. Centralize the business rule where possible, then use the Client Script only for faster user feedback.

Testing checklist for a mandatory sublist field

Test the implementation in a sandbox before deploying it to production. The test should cover both expected success cases and deliberate failures.

At minimum, verify that:

  1. A new record with a valid value on every applicable line saves successfully.

  2. A new record with one blank line fails and identifies the correct line.

  3. An edited record cannot remove a required value unless the business rule allows it.

  4. A copied record behaves as intended.

  5. A line that is exempt from the rule does not create a false error.

  6. A CSV import with a missing value is rejected.

  7. A RESTlet, web service, or scheduled process receives a usable error.

  8. The rule behaves correctly on every relevant custom form.

  9. Records with zero sublist lines follow the intended business behavior.

  10. The script does not interfere with delete, approval, or other unrelated actions.

Use execution logs to confirm the deployed script runs in the expected execution context. Also test with the actual roles that create and edit records. A script can appear correct for an administrator while producing an unexpected permission or form behavior for a restricted role.

If the field is sourced automatically, test timing carefully. A value that appears after a user selects another field might not be available when `validateLine` runs, depending on sourcing behavior. The server-side check should remain the final authority.

Is it possible to enforce a mandatory value without making the field visibly mandatory?

Yes, but we do not recommend hiding an important requirement from users. A server-side `beforeSubmit` validation can enforce the value while leaving the field’s visual mandatory setting unchanged.

This approach is appropriate when the requirement applies only to specific conditions, such as a subsidiary, transaction type, item category, or approval stage. In those cases, marking the field mandatory for every UI user could be misleading because the field is not universally required.

A conditional UI rule can also be implemented in `beforeLoad`, but the condition must match the server-side logic closely. If the browser says a value is optional while the User Event rejects the record, users experience the rule as unpredictable. The best design communicates the requirement in the UI and enforces the same requirement on the server.

What does this implementation cost?

The cost of making a NetSuite sublist field mandatory depends on whether the requirement is a simple form change or a multi-channel validation rule. A single form-level adjustment is smaller than a solution that includes Client Script feedback, User Event enforcement, integration testing, deployment, and support for multiple transaction types.

Before estimating the work, define the sublist, field ID, applicable line types, record events, custom forms, and entry channels. These details determine whether one shared script is sufficient or whether separate deployments and conditions are needed.

If the requirement affects integrated transactions or financial records, include testing and error-message design in the scope. Preventing an incomplete record is only useful if the person or system sending the record can understand how to correct it. For help assessing the right implementation, contact our NetSuite team.

Conclusion

A reliable mandatory NetSuite sublist field implementation needs more than a visual form setting. Use `beforeLoad` and `serverWidget` to guide users, `validateLine` for immediate browser feedback, and `beforeSubmit` to validate every applicable line before NetSuite saves the record.

The most important design decision is to separate user experience from data enforcement. Once the field requirement is defined by record type, line type, execution context, and integration path, SuiteScript can enforce it consistently without creating unnecessary failures for valid records.

Looking for NetSuite Solutions?

Explore our expert NetSuite services and get started today.

Get Started
CTA Illustration

Frequently Asked Questions

How do I make a sublist field mandatory in NetSuite?

Use a `beforeLoad` User Event with `serverWidget` to set the sublist field’s `isMandatory` property to `true`. Add a `beforeSubmit` User Event that loops through every applicable sublist line and throws an error when the value is missing. The second layer is required for imports and integrations.

Does setting isMandatory work for NetSuite sublist fields?

Yes, setting `isMandatory = true` on the field returned from a sublist object makes the field appear required on the relevant NetSuite form. It controls the user interface, not every method of record creation. Server-side validation is still necessary when records can enter NetSuite through CSV, REST, SOAP, or scripts.

Can a workflow make a NetSuite sublist field required?

A workflow can handle simple field and record conditions, but it is not always the best tool for validating every line across multiple entry channels. SuiteScript is more suitable when the rule requires line iteration, conditional exemptions, integration enforcement, or line-specific error messages.

Is SuiteScript required to make a NetSuite sublist field mandatory?

SuiteScript is not always required for a basic field configuration on a standard form, but it is required when the mandatory rule must be applied dynamically or enforced consistently across integrations and server-side processes. A Client Script alone is not sufficient because it does not run in every execution context.

How do I validate every line in a NetSuite sublist?

Use `getLineCount()` to determine the number of lines, then call `getSublistValue()` for the target field at each line index. Reject the record when an applicable line contains `null`, `undefined`, or a blank value. Use `getCurrentSublistValue()` instead when validating the line currently being edited in a Client Script.

Why does my mandatory sublist field still allow CSV imports with blank values?

The form-level mandatory setting does not necessarily enforce the rule during CSV imports. Add a `beforeSubmit` User Event that validates the submitted record server-side, then test the deployment and execution context used by the import. Also confirm that the script is deployed to the correct record type and event.