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
- 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
- Do not issue concurrent delete requests for the same item
- Check ItemDeletion.isRegistered before calling delete in automation
- Guard UI delete buttons against double-submission
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
- Failed to delete {0}
- The name “{0}” is already in use.
- Failed to join the process
- No ancestor of type {} in the request
- No such job '
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/135a7d490c879efb.
Report an issue: GitHub.