# M3 API Error: Record already exist

> Source: https://netray.co/erp-help/m3-mi-program-record-already-exist-error
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## 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.

## Kind

error

## System

infor-m3

## Erp

Infor M3 (M3 Business Engine)

## Module

M3 API / MI Programs

## Query

M3 API error: Record already exist

## Alternate Queries

- 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

## Applies To

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

## Steps

### Diagnose and fix Record already exist

**Items:**

Capture 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.

Identify 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.

Run 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).

If 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.

If 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.

Add 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.

For 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.

Re-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.

## Sections

### How MI programs report errors

**Body:**

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.

**Code:**

<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

**Body:**

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

**Body:**

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

**Body:**

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.

## 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.

## Ai Angle

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.

## Faq

### Does Record already exist mean the whole transaction failed?

**Answer:** 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?

**Answer:** 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?

**Answer:** 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?

**Answer:** 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.

## Search terms

M3 API record already exist, M3 MI Add error, M3 errorType errorField, M3 API errorMessage, MvxAPI duplicate key error, M3 API idempotent integration, m3api-rest error handling, OIS100MI Add error, M3 API Chg vs Add, Infor M3 duplicate record error

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
