Error fixMicrosoft Dynamics 365 Business CentralAL Development / Concurrency

Business Central: "Another user has modified the record after you retrieved it"

Error
Another user has modified the record after you retrieved it from the database Business Central

Also searched as

  • business central record was changed by another user error
  • business central AL LockTable concurrency modify error
  • business central if-match etag 412 precondition failed

Short answer

Business Central uses optimistic concurrency. Every record carries a row version, and a write is rejected if the stored version no longer matches what you read. For users, refresh the page and redo the edit. For developers, read and modify in the same short transaction, use LockTable or the right read isolation, and send an If-Match ETag from API clients.

Applies to: Business Central online and on-premises, AL extensions and web service clients

How to resolve it

  1. 1As a user, refresh the page (or close and reopen the card) so you get the current record, then re-enter your change and save.
  2. 2Ask who else is editing. Open the Sessions list (Search: Sessions, or the Users page) and check for background sessions such as job queue entries working on the same record.
  3. 3Check Job Queue Entries for jobs touching the same table at the same time as users, and move heavy jobs to an off-hours schedule.
  4. 4As a developer, find the code that reads and later writes the record. Make sure the Get and Modify happen in the same transaction without a Commit or user interaction in between.
  5. 5Call Rec.LockTable() before reading when you intend to modify, so other sessions wait instead of racing you. Keep the locked window short.
  6. 6For API and OData clients, fetch the record, keep its ETag, and send it in the If-Match header on PATCH. Handle a 412 response by re-reading and retrying.
  7. 7Avoid modifying the same record from event subscribers that fire during a long posting routine, as these cause the conflict for the page that triggered the post.
  8. 8Log the table and primary key in your error handler so repeated conflicts can be traced to one hot record.

How optimistic concurrency works here

Business Central does not lock a record when you open a card. Each table row has a hidden SystemModifiedAt value and an underlying SQL row version. When a page saves, the runtime checks that the version of the row in the database equals the version it read earlier. If another session has written the row in between, the check fails and you see the message.

This is intentional. It prevents a user with a stale screen from silently overwriting someone else's change. The cost is that on busy records, such as a sales header being posted while someone edits it, conflicts are normal and should be handled rather than prevented.

In the web client the fix is a refresh. The harder cases come from automation: job queue entries, web services and event subscribers that touch the same rows as interactive users.

Fixing it in AL

The common AL defect is reading a record, doing slow work (a web call, a dialog, a Commit), and then calling Modify. Between the read and the write another session changes the row. Restructure so the read and the write are adjacent. If you must do slow work first, do it before the Get, then Get and Modify in a short block.

When you need to guarantee exclusivity for a read-modify-write, call LockTable on the record variable before the Get. In newer runtime versions you can also set the ReadIsolation property on the record to UpdLock. Both make the read take an update lock so competing writers wait. Keep the lock window short, because long locks produce timeouts and deadlocks for everyone else.

Never swallow the error with an empty if-not-then. If the modification fails, either retry once after re-reading the record or surface the conflict to the caller. Silent failure creates data that looks saved and is not.

procedure BumpPriority(ItemNo: Code[20])
var
    Item: Record Item;
begin
    Item.LockTable();
    if Item.Get(ItemNo) then begin
        Item.Description := CopyStr('Updated ' + Item.Description, 1, MaxStrLen(Item.Description));
        Item.Modify(true);
    end;
end;

API clients and integrations

The standard APIs return an ETag with each record (the @odata.etag value). A PATCH or DELETE must send it in the If-Match header. If someone changed the record after you read it, Business Central answers 412 Precondition Failed. That is the same concurrency check, expressed over HTTP.

The correct client pattern is: GET the record, apply the change, PATCH with If-Match, and on 412 re-GET and reapply. Sending If-Match with an asterisk bypasses the check and can overwrite another user's change, so use it only for data you own exclusively.

Integrations that update thousands of records in parallel often cause their own conflicts when two threads patch the same parent, such as a sales header and its lines. Serialise per parent document rather than adding retries blindly.

PATCH /api/v2.0/companies({companyId})/customers({customerId})
If-Match: W/"JzE5OzMwNTc4MzQ5..."
Content-Type: application/json

{ "phoneNumber": "555-0100" }

Common pitfalls

  • !Holding a record variable across a Commit or a dialog and then modifying it.
  • !Using LockTable broadly or for long operations, which turns conflicts into timeouts and deadlocks.
  • !Sending If-Match with an asterisk to make 412 errors go away, which overwrites other users' changes.
  • !Running heavy job queue entries on the same tables during business hours.
  • !Catching and ignoring the error so a failed save looks like success.

How an ERP-grounded AI assistant handles this

Diagnosing which session or job collides with users is a log-reading task. A grounded assistant can correlate the failing table and key with job queue entries, change log rows and session activity, and tell you which scheduled job and which user overlapped. ERPray works read-only on that data and shows the query. Fixing the code or the schedule is still a developer's change, and a model should not auto-retry writes.

Frequently asked questions

Why does Business Central say another user modified the record?

Business Central uses optimistic concurrency. It remembers the row version when you read a record and rejects the save if the stored version has changed since. Another user, a job queue entry or an event subscriber wrote the row first. Refresh the page and re-apply your edit.

Does LockTable fix this error in AL?

Often, when used correctly. Calling LockTable before the Get makes the read take an update lock so competing writers wait. It only works if the read and Modify happen in the same short transaction. Long locks cause timeouts, so keep the locked section small.

What does HTTP 412 mean from the Business Central API?

It is the same concurrency check over HTTP. You sent an If-Match ETag that no longer matches the record, because someone changed it after your GET. Read the record again, reapply your change, and send the new ETag. Do not bypass it unless you own the data.

Can a job queue entry cause this for users?

Yes. A job that updates the same table or record that users edit, such as sales documents or items, can change the row between a user's read and save. Check Job Queue Entries for overlapping schedules and move heavy jobs outside working hours where possible.

Related

Error fix

Fixing "You do not have the following permissions on TableData (table): (permission)" in Business Central AL

This runtime error means the current user's assigned permission sets do not grant the required Insert, Modify, Delete, Read, or Execute right on that specific table. It is most common right after installing or updating a custom AL extension, because Business Central checks object-level permissions even for tables an extension owns.

How-to

How to call an external REST API from AL in Business Central

Use the HttpClient, HttpRequestMessage, HttpResponseMessage and HttpContent types in AL, send the request with Send, check IsSuccessStatusCode, and parse the body with JsonObject.ReadFrom. Make sure the extension has Allow HttpClient Requests turned on, and keep tokens out of source code. Keep calls short, because they run inside the AL session.

How-to

Calling and extending the Business Central API v2.0

The Business Central API v2.0 is a REST/OData endpoint at api.businesscentral.dynamics.com/v2.0/{tenant}/{environment}/api/v2.0, authenticated with Azure AD OAuth 2.0. It exposes standard entities like customers and items, and lets you publish your own with an AL API page.

Error fix

Fixing "Cannot create a record in (table). The record already exists" in D365 F&SCM data entity imports

This is the standard kernel duplicate-key exception, thrown when the Data Management Framework tries to insert a staging row into a target table whose unique or alternate key already matches an existing record. It almost always means the entity's insert-vs-update logic did not recognize the target row as an update, not that you have a true accidental duplicate in your source file.

Error fix

Fixing "There are currently no batch servers available for processing" in D365 F&SCM

This message means the batch framework cannot find any AOS instance flagged as a batch server and available for the batch group the job is assigned to. The fix is almost always in server configuration (System administration > Servers) or batch group assignment, not in the batch job itself.

Error fix

Fixing "The CIL object was not found" in Dynamics AX 2012

This error appears when the AOS tries to execute compiled CIL for a class or method that has not actually been regenerated since a code change was imported or edited, so the .NET runtime has nothing matching to run. The fix is a full compile followed by a full CIL generation and an AOS restart, not just a partial or incremental rebuild.

AI for ERP

AI for Dynamics 365 Business Central, on-premises or SaaS, beyond Copilot

AI for Business Central beyond Copilot: grounded question answering over BC's data via OData and APIs, for on-premises and SaaS tenants alike.

Stuck on Microsoft Dynamics 365 Business Central?

Talk to engineers who work inside Microsoft Dynamics 365 Business Central every week, and who build private AI that answers these questions from your own ERP data.