🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Object is already deleted
This page was created by Lars.olofsson on 2022-12-28. Last edited by Wikiadmin on 2026-07-29.

You can prevent the Object is already deleted error by checking that an object still exists before an EAL action deletes or updates it.

What the error means

The error means that your EAL attempts to delete an object that has already been marked for deletion in the current transaction.

The delete operator marks an object for removal from persistence. The object is permanently removed at the next save operation. Before that save, the object can still be reachable through a reference that was obtained earlier in the ECO space. A later action can therefore reach the same object and attempt to delete it again.

Guard a delete with `existing`

Use the existing operator before calling `delete`. `existing` returns true when the object has not been deleted.

object.existing.whenTrue(object.delete)

In this example, `object` is a reference to the object you intend to delete.

State of `object` Result of the expression
The object has not been deleted `existing` is true and `object.delete` runs.
The object was already marked for deletion in this transaction `existing` is false and `object.delete` does not run.

Find and correct the second delete

When you see this error in a client or log, find every EAL path that can act on the same object during one save cycle.

  1. Locate the action or method that calls `delete`.
  2. Check whether another action, method, or object event can delete the same object first.
  3. Add an `existing` guard at the point where the object may already have been deleted.
  4. Save and retest the flow, including the case where the first deletion has already occurred.

For example, if one action deletes an order and a later action still holds a reference to that order, guard the later action:

order.existing.whenTrue(order.delete)

Do not use this guard to hide an unintended duplicate delete without investigating why both paths run. The guard prevents the exception; the model behavior must still match the intended deletion flow.

Check object event methods

OnUpdate runs before an object is saved. An object can have been marked for deletion before this event is reached, so update logic must not modify it in that state.

Use an `existing` check in `OnUpdate` when the method changes the object:

if self.existing then
  self.ChangeTime:=DateTime.Now;
  false
else
  false
endif

Object event methods such as `OnCreate`, `OnUpdate`, and OnDelete are EAL methods: they must have IsQuery set to false. See Documentation:Acting on object changes for the event-method rules and examples.

Delete an object versus remove a link

Use `delete` when the object itself must be removed from persistence. If you only need to detach an object from a collection or association, use remove instead. `remove` changes the association link; it does not delete the object.

For example, removing an order from a customer's Orders collection keeps the Order object:

vCurrent_Customer.Orders.remove(order)

See also