elastic/elasticsearch · warning · GradleException

Failed to delete some files: {files}

Error message

Failed to delete some files:

{files}

What it means

Thrown by PruneChangelogsTask after attempting to delete a set of changelog files deemed safe to remove. The deleteHelper.deleteFiles call returns the subset it could not delete; if that set is non-empty, the task lists the survivors (relative to rootDir) and throws a GradleException so the operator knows which files remain.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/PruneChangelogsTask.java:113

        }

        final Set<File> filesToDelete = allFilesInCheckout.stream()
            .filter(each -> earlierFiles.contains(each.getName()))
            .collect(Collectors.toCollection(TreeSet::new));

        if (filesToDelete.isEmpty()) {
            LOGGER.warn("No files need to be deleted.");
            return;
        }

        LOGGER.warn("The following changelog files will be deleted:");
        LOGGER.warn("");
        filesToDelete.forEach(file -> LOGGER.warn("\t{}", rootDir.relativize(file.toPath())));

        final Set<File> failedToDelete = deleteHelper.deleteFiles(filesToDelete);

        if (failedToDelete.isEmpty() == false) {
            throw new GradleException(
                "Failed to delete some files:\n\n"
                    + failedToDelete.stream().map(file -> "\t" + rootDir.relativize(file.toPath())).collect(Collectors.joining("\n"))
                    + "\n"
            );
        }
    }

    /**
     * Find the releases prior to the supplied version, and find the changelog files in those releases by inspecting the
     * git trees at each tag.
     * <p>
     * If the supplied version is the very first in a new major series, then the method will look tag in the previous
     * major series. Otherwise, all git tags in the current major series will be inspected.
     *
     * @param gitWrapper used for git operations
     * @param version the git history is inspected relative to this version
     * @return filenames for changelog files in previous releases, without any path
     */

View on GitHub (pinned to db6a809a66)

Solutions

  1. Close editors/IDEs and any process that may hold the listed files open, then re-run pruneChangelogs.
  2. Check and fix permissions on the surviving files (e.g. chmod u+w) and their parent directories.
  3. On Windows, ensure no file explorer/antivirus has the files locked.
  4. Re-run the task; if specific files persistently fail, delete them manually and re-run to confirm the remainder succeed.
Defensive patterns

Strategy: retry

Validate before calling

// Preflight: ensure files are deletable
for (File f : filesToDelete) {
    if (f.exists() && f.canWrite() == false) f.setWritable(true);
}

Try / catch

Set<File> failed = deleteHelper.deleteFiles(filesToDelete);
if (failed.isEmpty() == false) {
    // close handles / fix perms, then retry once
    failed.forEach(f -> f.setWritable(true));
    failed = deleteHelper.deleteFiles(failed);
    if (failed.isEmpty() == false) throw new GradleException("Failed to delete: " + failed);
}

Prevention

When it happens

Trigger: The task computed filesToDelete (changelogs already represented elsewhere/released), called deleteFiles, and some deletions failed. Typical causes: a file is locked by another process, has read-only permissions, or the JVM lacks delete permission on the parent directory.

Common situations: An IDE or file watcher holding a handle on a changelog YAML on Windows/locked fs; read-only file permissions from a git checkout or packaging step; another Gradle process or editor holding the file; running the prune task without write permission to the changelog tree.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/f47fed39a4681064. Report an issue: GitHub.