Doug it sounds like the physical table SO_InvoiceDetail is missing the KPRIMARY (clustered) index. For the short term you can remove the extra row in SO_InvoiceDetail (extra b/c it shares the same InvoiceNo + LineKey). Probably somebody was editing the line but b/c the index is missing it INSERTed a new row for that item code instead of UPDATEing it.
For the larger problem you'll want to see if the dictionary for SO_InvoiceDetail is either missing KPRIMARY or it's there but missing in the Providex.KDF. In case you have the DD util, going to send you a chat with some steps should you need it: