jenkinsci/jenkins · warning · Failure

{0} is currently being deleted

Error message

{0} is currently being deleted

What it means

Thrown by AbstractItem.delete() when the current thread does not own the deletion registration AND the item is already registered as being deleted by another thread. ItemDeletion.register(this) returns false (not owner) and ItemDeletion.isRegistered(this) returns true, indicating a concurrent delete is in progress. The Failure (Stapler) prevents the second caller from proceeding and shows the localized 'BeingDeleted' message with the item's pronoun.

Source

Thrown at core/src/main/java/hudson/model/AbstractItem.java:791

    }

    /**
     * Deletes this item.
     *
     * <p>
     * Any exception indicates the deletion has failed, but {@link AbortException} would prevent the caller
     * from showing the stack trace.
     * @see ItemDeletion
     */
    @Override
    public void delete() throws IOException, InterruptedException {
        checkPermission(DELETE);
        ItemListener.checkBeforeDelete(this);
        boolean responsibleForAbortingBuilds = !ItemDeletion.contains(this);
        boolean ownsRegistration = ItemDeletion.register(this);
        if (!ownsRegistration && ItemDeletion.isRegistered(this)) {
            // we are not the owning thread and somebody else is concurrently deleting this exact item
            throw new Failure(Messages.AbstractItem_BeingDeleted(getPronoun()));
        }
        try {
            // if a build is in progress. Cancel it.
            if (responsibleForAbortingBuilds || ownsRegistration) {
                ItemDeletion.cancelBuildsInProgress(this);
            }
            if (this instanceof ItemGroup) {
                // delete individual items first
                // (disregard whether they would be deletable in isolation)
                // JENKINS-34939: do not hold the monitor on this folder while deleting them
                // (thus we cannot do this inside performDelete)
                try (ACLContext oldContext = ACL.as2(ACL.SYSTEM2)) {
                    for (Item i : ((ItemGroup<?>) this).getItems(TopLevelItem.class::isInstance)) {
                        try {
                            i.delete();
                        } catch (AbortException e) {
                            throw (AbortException) new AbortException(
                                    "Failed to delete " + i.getFullDisplayName() + " : " + e.getMessage()).initCause(e);

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Avoid issuing concurrent delete requests for the same item; serialize deletions

Example fix

// before: concurrent deletes race
try { item.delete(); } catch (Failure f) { /* ignored */ }
// after: check deletion status first
if (ItemDeletion.isRegistered(item)) {
    throw new Failure(item.getFullDisplayName() + " is already being deleted");
}
item.delete();
Defensive patterns

Strategy: validation

Validate before calling

if (ItemDeletion.isRegistered(item)) {
    throw new IllegalStateException(item.getFullDisplayName() + " is already being deleted");
}

Try / catch

try {
    item.delete();
} catch (Failure f) {
    if (f.getMessage().contains("currently being deleted")) {
        // concurrent delete in progress; inform user or retry after a short delay
    }
    throw f;
}

Prevention

When it happens

Trigger: Two concurrent requests/threads call delete() on the same item; the first thread registers as owner, the second thread hits the 'not owner but registered' branch and throws Failure.

Common situations: User clicks delete twice rapidly; a REST/CLI delete coincides with a UI delete; an automation script and a manual action race on the same job; a folder deletion iterating children while a child is concurrently deleted.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/135a7d490c879efb. Report an issue: GitHub.