Skip to main content
Question

Error: Key field cannot start with a leading space.

  • February 13, 2026
  • 6 replies
  • 72 views

Forum|alt.badge.img

Hello everyone,

We have an inventory item with the tracking method set to “Track Serial Numbers”, which allows users to manually enter serial numbers.

We recently added a feature for some inventory items to auto-generate serial numbers from a numbering sequence on the Save action.

However, when trying to assign the generated serial number to the Lot/Serial Number field during Save, we encounter the following error:

“Key field cannot start with a leading space.”

We are confident that the serial number generated from the numbering sequence does not contain any spaces.

Could someone advise on the correct approach to assign auto-generated serial numbers to serial-tracked inventory items on Save without triggering this error?

Thank you in advance!

 

protected virtual void POReceiptLine_RowPersisting(PXCache sender, PXRowPersistingEventArgs e, PXRowPersisting BaseEvent)
{
    BaseEvent.Invoke(sender, e);

    var lineitem = (POReceiptLine)e.Row;

    if (lineitem == null)
        return;

    if (Convert.ToString(e.Operation) == "Normal, Insert" || Convert.ToString(e.Operation) == "Normal, Update")
    {
        string serialNbr = AutoNumberAttribute.GetNextNumber(sender, lineitem, numSeq, Base.Accessinfo.BusinessDate);

        Base.transactions.SetValueExt<POReceiptLine.lotSerialNbr>(lineitem, serialNbr);      
    }
}

6 replies

Forum|alt.badge.img+3

Hello ​@ckwiat46 I think may be RowPersisting is too late, by the time RowPersisting runs, Acumatica has already validated.
You can try with RowInserting or RowUpdating on the Split. its rely on POReceiptLineSplit.

 

hope it helps.


DipakNilkanth
Pro III
Forum|alt.badge.img+14

Hi ​@ckwiat46,
For serial-tracked inventory, Lot/Serial numbers are handled through INLotSerialNbrAttribute and Validation and key checks happen before RowPersisting. The system expects lot/serial splits to already exist.

So when you are setting the value for lotSerialNbr at RowPersisting, the lot/serial attribute has already validated the key — which results in that error.
Try to move your code to RowInserted Event of POReceiptLine which will resolve your issue.


Forum|alt.badge.img+2
  • Jr Varsity III
  • February 17, 2026

@ckwiat46 ,Hi you can try like this example. Hope it will work.

protected virtual void POReceiptLineSplit_RowInserting(PXCache sender, PXRowInsertingEventArgs e)
{
var split = (POReceiptLineSplit)e.Row;
if (split == null) return;

if (split.InventoryID == null)
return;

InventoryItem item = InventoryItem.PK.Find(Base, split.InventoryID);
if (item?.LotSerClassID == null)
return;

INLotSerClass lotSerClass = INLotSerClass.PK.Find(Base, item.LotSerClassID);
if (lotSerClass?.LotSerTrack != INLotSerTrack.SerialNumbered)
return;

string serialNbr = AutoNumberAttribute.GetNextNumber(
sender,
split,
"YOURNUMBERSEQUENCE",
Base.Accessinfo.BusinessDate
);

split.LotSerialNbr = serialNbr?.Trim();
}

 


Forum|alt.badge.img+1
  • Jr Varsity I
  • February 17, 2026

Hi ​@ckwiat46,
 

The error occurs because LotSerialNbr is a key field and you are assigning it in RowPersisting, which is too late in the persistence cycle.

For serial-tracked items, LotSerialNbr is handled at the POReceiptLineSplit level and must be set before persistence begins.

Correct approach

Assign the serial number in POReceiptLineSplit_RowInserting (or FieldDefaulting).
Do not assign it on POReceiptLine and do not set it in RowPersisting.

Correct structured code : 
 

 protected virtual void POReceiptLineSplit_RowInserting(
        PXCache sender,
        PXRowInsertingEventArgs e)
    {
        var split = e.Row as POReceiptLineSplit;
        if (split == null)
            return;

        InventoryItem item = InventoryItem.PK.Find(Base, split.InventoryID);
        if (item == null)
            return;

        INLotSerClass lotSerClass = INLotSerClass.PK.Find(Base, item.LotSerClassID);
        if (lotSerClass == null || lotSerClass.LotSerTrack != INLotSerTrack.SerialNumbered)
            return;

        if (split.Qty != 1m)
            return;

        if (string.IsNullOrEmpty(split.LotSerialNbr))
        {
            string serialNbr = AutoNumberAttribute.GetNextNumber(
                sender,
                split,
                "YOURNUMBERINGSEQUENCEID",   // replace with your numbering sequence ID
                Base.Accessinfo.BusinessDate);

            split.LotSerialNbr = serialNbr;
        }
    }

Hope its help you.


Forum|alt.badge.img
  • Author
  • Jr Varsity III
  • February 18, 2026

Hello Everyone, the problem here is, what if user entered the inventory id and it generated a number based on numbering sequence, then user deleted the inventory id, here we loose a number.


Forum|alt.badge.img+1
  • Jr Varsity I
  • February 18, 2026

Hello Everyone, the problem here is, what if user entered the inventory id and it generated a number based on numbering sequence, then user deleted the inventory id, here we loose a number.

Hello ​@ckwiat46 

What you described is standard behavior in Acumatica. When a serial number is generated through a numbering sequence and the record is not saved or is deleted, that number is still consumed. The system will automatically move to the next number for the next record.

Regarding the leading space error, if possible, please share a screenshot of your Numbering Sequence setup so we can review it.

I also suggest deleting the existing numbering sequence and creating a new one. Sometimes recreating the sequence resolves the issue.