Error fixInfor M3 (M3 Business Engine)M3 API / MI Programs

M3 API Error: Record already exist

Error
M3 API error: Record already exist

Also searched as

  • M3 MI Add transaction fails with Record already exist
  • errorMessage Record already exist M3 API
  • M3 API errorType errorField meaning
  • why does M3 MI Add return a duplicate key error

Short answer

Record already exist means the MI Add transaction you called is trying to insert a key that is already present in the target M3 table, most often because a prior call succeeded and was retried, or because the key fields you built do not match what you think they match. Read the errorField and errorFieldGroup attributes on the response to see exactly which key field M3 flagged, then either switch to the matching Chg (change) transaction or fix the key construction in the caller.

Applies to: Infor M3 Business Engine 10.x-14.x (Movex/M3 UI Adapter, MvxAPI, m3api-rest, ION API), all inbound MI Add transactions

Diagnose and fix Record already exist

  1. 1Capture the full MI response, not just the message text - the errorType, errorField, errorFieldGroup and errorMessage attributes on the response record tell you which key field failed and why.
  2. 2Identify the table behind the MI program (check the MI program's transaction description or the M3 Data Dictionary) so you know the real primary key, not just the fields your integration happens to send.
  3. 3Run the equivalent MI Get or List transaction with the same key values the failed Add used, to confirm the record genuinely exists (versus a case-sensitivity or leading-zero mismatch in the key).
  4. 4If the record exists and should be updated, switch the caller to the corresponding Chg transaction (for example OIS100MI.Add to OIS100MI.Chg) instead of retrying Add.
  5. 5If the record should not exist, check for a duplicate call - integration middleware (ION, MEC, a custom REST client) retrying a timed-out request is the most common real cause.
  6. 6Add idempotency on the caller side: do a Get before every Add, or catch errorType for this specific error and treat it as a soft success rather than a hard failure.
  7. 7For batch loads, pre-stage keys and run a bulk existence check against the target table before looping MI Add calls one row at a time.
  8. 8Re-run the corrected call and confirm the response returns no errorType attribute at all - that is the only reliable signal of success across MI programs.

How MI programs report errors

Every M3 API (MI) transaction response - whether you call it over the classic MvxAPI SOAP adapter, the m3api-rest wrapper, or ION API - carries error information as attributes on the record element rather than as a separate exception object. When a call fails you get errorType (a short code such as 10, 20 or 30 describing the class of error), errorField (the specific input field M3 rejected), errorFieldGroup, and errorMessage (the human-readable text, of which Record already exist is one of the most common).

This matters because the same errorMessage text can come from different fields depending on the program. Record already exist on a sales order line Add (OIS100MI) usually points at the OrderNumber and LineNumber combination; on an item master Add (MMS200MI) it points at the ItemNumber. Always check errorField before assuming which key collided - do not guess from the program name alone.

<MIRecord>
  <NameValuePair Name="CONO">100</NameValuePair>
  <NameValuePair Name="ITNO">ITEM-4471</NameValuePair>
</MIRecord>
<!-- error response attributes -->
errorType="30" errorField="ITNO" errorFieldGroup="KEY"
errorMessage="Record already exist"

The usual real causes

The single most frequent cause in production is a network or timeout retry: the first Add actually succeeded on the M3 side, the caller (often an ION flow, a MEC process, or a custom .NET/Java client) never received the confirmation, and it resends the same payload. From the client's point of view the call failed; from M3's point of view the record is already there.

The second most common cause is a key-construction bug in the caller - padding, casing, or a company/division (CONO) value that differs from what was used the first time, so two logically different-looking calls collide on the same physical key. The third is a genuine race condition between two integrations (for example a web storefront and a batch EDI load) both trying to create the same customer or item at nearly the same time.

Add versus Chg versus AddOrChg patterns

Most MI programs expose separate Add and Chg transactions and expect the caller to know which one applies; a handful (for example some CRS and MMS programs) expose an Upd or AddOrChg-style transaction that upserts. When you are writing new integration code against M3, prefer a Get-then-branch pattern over relying on Add always succeeding: call Get first, and route to Add on 'not found' or Chg on 'found'. It costs one extra API call per record but eliminates this entire error class.

For high-volume batch interfaces this Get-then-branch pattern is too slow row by row; instead stage the incoming keys in a work table, run one bulk comparison against the M3 side (via a List transaction or a read-only view on the underlying table), and split the batch into insert and update sets before you start calling MI Add or Chg.

Idempotent integration design

Because M3 API calls over HTTP-based adapters can time out without the caller knowing whether the write committed, treat Record already exist on Add (and the mirror-image Record does not exist on Chg) as expected outcomes to catch and swallow, not as fatal errors to alert on. Log them at a lower severity than a genuine field validation error, and only escalate if the rate spikes, which usually signals a real duplicate-submission bug upstream rather than normal retry noise.

Common pitfalls

  • !Reading only errorMessage and ignoring errorField - the same message text can point at completely different key fields depending on the MI program.
  • !Assuming the MI program name tells you the underlying table; several M3 programs write to more than one table and the key that collided may belong to a secondary table, not the obvious one.
  • !Retrying a failed Add automatically without first checking whether the original call actually succeeded server-side - this turns one legitimate write into a permanent Record already exist loop.
  • !Forgetting that CONO (company) and DIVI (division) are part of the key on most M3 tables - a call built for the wrong division will look like a totally different record and mask real duplicates.
  • !Building batch loaders that call Add in a tight loop with no pre-check, which is slow and guarantees this error on every re-run of a partially failed batch.
  • !Mixing up leading zeros or case sensitivity in alphanumeric keys such as item number or customer number, which M3 treats as significant even when your source system does not.

How an ERP-grounded AI assistant handles this

ERPray, Netray's grounded assistant for M3, sits in front of the same MI programs and already knows which key fields matter per transaction, so when an integration throws Record already exist it can look up the real record with a Get call, show the requester what already exists, and suggest the matching Chg call instead of a blind retry - all logged for review rather than executed automatically.

Frequently asked questions

Does Record already exist mean the whole transaction failed?

Yes for that specific Add call - M3 does not partially commit a single MI transaction. If you are inside a multi-line batch or a MEC document with several transactions, only the failed line is affected; earlier successful lines in the same batch remain committed.

Is there a generic upsert transaction I can use instead of Add/Chg?

Some MI programs offer it, most do not. Check the program's transaction list (via MNS150 API metadata or the M3 API reference for that program) for an Upd or combined transaction before assuming you must branch between Add and Chg yourself.

Why does the same payload work in one environment but throw Record already exist in another?

Most often the target environment already has test or migrated data with those keys loaded, or the CONO/DIVI values differ between environments so the same-looking call resolves to a different, already-populated key.

Can I catch this error by errorType code instead of parsing errorMessage text?

Yes, and you should - errorType is a stable numeric/short code while errorMessage text can vary slightly by language pack. Build your integration's error handling around errorType plus errorField, using errorMessage only for logging.

Related

Advanced

Paging M3 API MI List Transactions Past the Default Record Limit

M3 List transactions (the read/browse transaction most MI programs expose, such as CRS610MI.LstByNumber or OIS100MI.LstOrderHead) cap the rows returned per call using the MaxReturnedRecords input field, and by default many clients leave it low or unset, which looks like the API silently truncating results. Set MaxReturnedRecords explicitly, then loop the call using the last key values from the previous page as the starting position until fewer rows than the limit come back.

Error fix

M3 API Error: Not Authorized to Program

Not authorized to program (or the equivalent transaction-level authorization error) means the M3 user ID the integration authenticates as can log in fine but has not been granted access to that specific MI program, transaction, or company/division through its authority group. Fixing it means adding the program/transaction to the integration user's authority group in M3, not changing anything in the calling code.

How-to

How to Build a Grid Mapping in M3 Enterprise Collaborator (MEC)

M3 Enterprise Collaborator (MEC) moves data between an external format (EDI, flat file, XML) and M3's own API by chaining a collection step (getting the document in), a grid mapping step (field-level transformation from source structure to M3 API call structure), and a delivery step (executing the mapped MI transaction). Building a new mapping means defining the source document structure, building the grid that maps each source field to its M3 API field, and testing with representative sample documents before going live.

How-to

How to Add a Personalization Script to an M3 H5 Panel

M3 H5 lets an administrator attach a JavaScript personalization script to a specific panel of a specific program, using the MForms client API to read fields, react to panel and field events, and adjust the UI (hide fields, set defaults, validate input) without modifying the underlying M3 program. Scripts are written and attached through Personalization mode in H5, saved against the panel/program combination, and deployed to the users or roles who should see the behavior.

How-to

How to Create a New Item in M3 (MMS001)

A new item in M3 is created in two stages: item basic data in MMS001 (Item. Open), which defines company-wide attributes such as description, item group and unit of measure, then facility-level data in MMS002 (Item/Facility. Connect), which attaches the item to a specific warehouse or plant with purchasing, planning and costing parameters. An item is not usable for orders, purchasing or MRP until both stages are complete.

How-to

How to Enter a Customer Order in M3 (OIS100)

OIS100 (Customer Order. Open) is the primary M3 program for entering and maintaining customer orders, built as a header-then-line workflow: you first create the order header with customer, order type and delivery terms, then add order lines that each carry their own item, quantity, price and delivery date defaulted from customer and item agreements.

AI for ERP

AI for Infor M3: A Practical Path from MI Programs to a Private Assistant

Add grounded AI to Infor M3: natural-language answers over MI programs and MEC, agents for distribution and manufacturing, on-prem or private cloud in Europe.

AI for ERP

AI Agents Over Infor ION API, BODs, and the Infor Data Lake

Build AI agents on Infor ION API Gateway, BODs, and Data Lake, alongside or instead of Infor's own GenAI features, with your choice of model and hosting.

Stuck on Infor M3 (M3 Business Engine)?

Talk to engineers who work inside Infor M3 (M3 Business Engine) every week, and who build private AI that answers these questions from your own ERP data.