The quick answer
currentRecord has no setSublistValue method. To update another editable child line, select it, call setCurrentSublistValue, then commitLine. Capture the user's chosen line before changing selection, and protect cross-line commits with a module-level guard. A parent Save is a separate step from committing a line.
This walkthrough uses fictional Inspection Plan and Inspection Version records, a local code editor and a currentRecord API model. The same saved source drives a bounded local form adapter. The result demonstrates that local exercise only; no account upload, deployment or native client execution is verified.
Before you start
The example has three existing child rows. Version A starts Current, and the user selects Version B. It enforces at most one for the demonstrated checkbox change; unchecking the last Current row permits zero.
For account use, the parent must be in Edit or Create, the child type must have Allow Child Record Editing enabled, and the user's role and form must allow changes. The child-record editing setting does not override role, form, field, record-state, workflow or script restrictions. A read-only child list cannot be made editable by choosing different scripting APIs. Oracle explains these settings in Configuring File and Child Record Settings.
Use the actual sublist and field IDs from your account. This example uses recmachcustrecord_inspection_plan and custrecord_current as placeholders. Confirm that the Client Script is attached to the intended form or has an applicable deployment before account testing. The recording uses prepared local script information.
Oracle documents CurrentRecord.selectLine, CurrentRecord.commitLine and sublistChanged. SuiteScript2.x line indexes start at zero. The event order shown below is observed in the local harness and needs separate account verification.
01. Inspect the saved child
Open Quarterly inspection in View. On the parent's Custom subtab, Version A shows Current Yes. Versions B and C show No. These prepared local records provide the comparison state.
02. Show the duplicate
Click Edit, select Version B's Current cell, check it, and commit the line with OK. The unrepaired local source has no supported normalization rule, so both A and B remain checked. These changes are unsaved. Click the parent Cancel to discard them.
The detail below isolates the Current column in row order A, B, C. Enlarge it to see the complete parent form and row names.
03. Diagnose the setter
Open current_child.js in the local Code Editor. Its fieldChanged captures the zero-based line index before the script moves selection. The module already has an updating guard and finally reset. The defect is inside the loop: it calls rec.setSublistValue.
Click Run local harness. The actual source runs against a stand-in currentRecord object, which has no such method. The red diagnostic is local; it is not a promised native NetSuite exception message.
04. Repair the sequence
This code is a local demonstration, not a verified native Client Script implementation. Confirm the fieldChanged → line commit → sublistChanged sequence in a sandbox. It assumes the user commits a checked existing line next. Canceling that line can leave pending stale; a later unrelated callback could clear another row. Numeric indexes also do not establish stable child identity. Handle these paths before account use.
Replace the unsupported call with the selected-line sequence, retaining the surrounding local module:
/**
* @NApiVersion 2.1
* @NScriptType ClientScript
*/
define([], () => {
const LIST = 'recmachcustrecord_inspection_plan';
const FIELD = 'custrecord_current';
let updating = false, pending = -1;
function fieldChanged(c) {
if (updating || c.sublistId !== LIST || c.fieldId !== FIELD) return;
const rec = c.currentRecord;
pending = rec.getCurrentSublistValue({sublistId: LIST, fieldId: FIELD})
? rec.getCurrentSublistIndex({sublistId: LIST}) : -1;
}
function sublistChanged(c) {
if (updating || c.sublistId !== LIST || pending < 0) return;
const rec = c.currentRecord, chosen = pending;
pending = -1;
updating = true;
try {
for (let line = 0; line < rec.getLineCount({sublistId: LIST}); line++) {
if (line === chosen) continue;
if (!rec.getSublistValue({sublistId: LIST, fieldId: FIELD, line})) continue;
rec.selectLine({sublistId: LIST, line});
rec.setCurrentSublistValue({sublistId: LIST, fieldId: FIELD,
value: false, ignoreFieldChange: true});
rec.commitLine({sublistId: LIST});
}
} finally {
try {
if (chosen < rec.getLineCount({sublistId: LIST}))
rec.selectLine({sublistId: LIST, line: chosen});
} finally { updating = false; }
}
}
return {fieldChanged, sublistChanged};
});
Keep the surrounding identity capture and guard. fieldChanged stores the line the user checked; sublistChanged consumes it after the harness commits that line. The updating flag remains true while other lines are committed. ignoreFieldChange suppresses the setter's field-change callback; it does not suppress sublistChanged callbacks caused by commitLine.
The finally block attempts to select the same numeric index if it still exists. It does not prove the original child still occupies that index. The nested finally resets updating even if selection fails; both update and restoration errors can propagate. Earlier edits may remain partly changed in memory after a later commit fails, so establish and test an error-handling policy before account use. Restoration is a selection only: do not recommit the chosen line. This small example assumes a checkbox change on an existing line followed by its commit. A production version must confirm the actual committed action and clear stale staged state on tested non-commit paths. Use a stable child key where available, re-resolve its line, and handle insertion, removal and reordering.
Click the local editor Save to save the source file, then Run local exercise. The model reports line0 false, line1 true and line2 false. It commits the old Current line and restores selection to line1. The saved source bytes are also applied to the local form adapter; this does not upload a File Cabinet file.
05. Choose Current
Reopen the parent in Edit. Select Version B's Current cell, check it, and commit with OK. The local adapter clears Version A while retaining Version B. Version C remains clear. The middle row alone is now checked, but the parent has not been saved.
06. Save and reload
Click the parent Save. In View, confirm Version A No, Version B Yes, Version C No. Reload and check the same values. The local adapter's parent Save has persisted its child changes.
Common questions
Why not use currentRecord.setSublistValue?
That is not a currentRecord method. For another editable line, use selectLine, setCurrentSublistValue and commitLine. Do not confuse the current form's API with the methods available on a record loaded through N/record.
Why does ignoreFieldChange not stop the loop?
It controls field-change behavior for the setter. Programmatic line commits can still cause sublistChanged. Keep a module-level guard active across the commits, return early during nested callbacks, and reset it in finally.
Why capture the line before the loop?
Selecting a different line changes what getCurrentSublistIndex returns. Keep the user's chosen index separately before moving selection. The example assumes stable existing rows and an immediate checkbox-line commit. Canceling the line can leave stale pending state in this sample. A production version must identify a confirmed commit, clear staged state on tested non-commit paths and use a stable child key where available.
Does this enforce exactly one Current child everywhere?
No. Unchecking the last Current row permits zero, and opening or saving without the demonstrated checkbox change does not automatically clean existing duplicates. Client-only behavior also does not establish uniqueness for imports, integrations, other scripts or concurrent users. Those paths require a separate server-side data-integrity design.
Is line commit the same as saving the parent?
No. The earlier line changes are unsaved form state. The recording's final Save and reload establish persistence only in the local exercise. Account deployment, permissions, event timing and persistence must be verified separately.