v10: Deferred Deletions [ADSContainer]

What hair I don't have I've ripped out... and I can't add any images in here as work blocks uploads to unauthorised repositories (like AWS).

Trying to add a custom DialogDeferredOperation entry (don't want whole class [ADSContainer] to defer with table setting), and I can get the entry added to DialogDeferredOperation and is correctly set for Delete at a future date with the correct ObjectKey using this script:

''' <summary>
''' Used to generate a deferred deletion for an ADS Container
''' </summary>
''' <param name="uidADSContainer">UID_ADSContainer to delete</param>
''' <param name="delayDays">Number of days to delay</param>
''' <param name="desc">Description for the deletion</param>
Public Sub CCC_ADSContainer_Deferred_Deletion(ByVal uidADSContainer As String, ByVal delayDays As Int32, ByVal desc As String)
    Using New VI.DB.DeferredOperations.DeferredBlock(Connection, DateTime.UtcNow.AddDays(delayDays), desc)
        Using uow = Connection.Session.StartUnitOfWork()
            Dim targetContainer As IEntity = Connection.Session.Source.CreateNew(Table.ADSContainer)
            targetContainer.PutValue(Table.ADSContainer.UID_ADSContainer, uidADSContainer)
            targetContainer.MarkForDeletionWithoutDelay()
            uow.Put(targetContainer)
            uow.Commit()
        End Using
    End Using
End Sub

Using "Connection" or "Session" makes no difference.

Now, when I EXECUTE the Deferred, it errors out with:

(2026-09-04 02:31:06.210) [810457] Error saving ADSContainer
[810306] Error running 'OnSaving' in logic module 'ADS.Customizer.ADSContainer'.
[2105410] This Active Directory object cannot be deleted or moved  because it is marked as protected from accidental deletion.

That is despite the fact that the object clearly has:

  • IsProtectedFromAccidentalDel = False
  • IsSystemContainer = False

I can also use Object Browser/Manager to delete the entity directly without any customizer complaints - so not sure why its kicking in with Job Queue.

Object State in DialogDeferred:

<Patch>
    <Key>
        <T>ADSContainer</T>
        <P>6300f440-5d7c-4923-a6a0-1dc8a919fa9f</P>
    </Key>
    <Diff>
        <Data State="Deleted, PermissionBased, ToDeletePhysical"/>
        <Op Columnname="UID_ADSContainer" Type="Value" ValType="String" AlreadyApplied="True">
            <OldValue/>
            <Value>6300f440-5d7c-4923-a6a0-1dc8a919fa9f</Value>
        </Op>
    </Diff>
</Patch>

Bug in Customizer?

  • Looking under the hood, the error [2105410] is thrown from ADSHelper.CheckIsProtectedFromAccidentalDel and has this condition:

    if (entity.GetValue<bool>("IsProtectedFromAccidentalDel") && (entity.IsDeleted() || entity.Isloaded && entity.Columns[containerColumn].IsChanged))

    where containerColumn defaults to UID_ADSContainer

    I think this is throwing because the XMarkedForDeletion is not > 0 (which puts me into a contradiction of not wanting to .MarkForDeletion() over direct Deferred).