elastic/elasticsearch · critical · IllegalStateException
Changelog directory contains changes that will be wiped out
Error message
Changelog directory contains changes that will be wiped out by this task:
{changelogDirectory}
{output} What it means
Thrown by BundleChangelogsTask.checkoutChangelogs before running `git rm -rf` on the changelog directory. It runs `git status --porcelain <changelogDir>`; if any output is produced (modified, staged, or untracked files exist), the task aborts to avoid silently destroying uncommitted changelog work during the checkout/restore sequence.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java:225
entries.sort(changelogEntryComparator());
ChangelogBundle bundle = new ChangelogBundle(version, finalize, Instant.now().toString(), entries);
yamlMapper.writeValue(new File("docs/release-notes/changelog-bundles/" + version + ".yml"), bundle);
} finally {
if (didCheckoutChangelogs) {
gitWrapper.runCommand("git", "restore", "-s@", "-SW", "--", changelogDirectory.get().toString());
}
}
}
private void checkoutChangelogs(GitWrapper gitWrapper, String upstream, String ref) {
gitWrapper.updateRemote(upstream);
// If the changelog directory contains modified/new files, we should error out instead of wiping them out silently
var output = gitWrapper.runCommand("git", "status", "--porcelain", changelogDirectory.get().toString()).trim();
if (output.isEmpty() == false) {
throw new IllegalStateException(
"Changelog directory contains changes that will be wiped out by this task:\n" + changelogDirectory.get() + "\n" + output
);
}
gitWrapper.runCommand("rm", "-rf", changelogDirectory.get().toString());
var refSpec = upstream + "/" + ref;
if (ref.contains("upstream/")) {
refSpec = ref.replace("upstream/", upstream + "/");
} else if (ref.matches("^[0-9a-f]+$")) {
refSpec = ref;
}
gitWrapper.runCommand("git", "checkout", refSpec, "--", changelogDirectory.get().toString());
}
private void addChangelogsFromRef(GitWrapper gitWrapper, String upstream, String ref) {
var refSpec = upstream + "/" + ref;
if (ref.contains("upstream/")) {
refSpec = ref.replace("upstream/", upstream + "/");View on GitHub (pinned to db6a809a66)
Solutions
- Commit, stash, or revert local changes in the changelog directory before running bundleChangelogs (git stash or git checkout -- <changelogDir>).
- If the changes are intentional and should be preserved, move them out of the directory or commit to a branch first.
- Re-run the task once `git status --porcelain <changelogDir>` is empty.
- If the dirty state is from a prior failed run, inspect and clean it deliberately rather than letting the task wipe it.
Example fix
// before: dirty changelog dir $ git status --porcelain changelogs/ ?? changelogs/heads-up/foo.yaml $ ./gradlew bundleChangelogs --branch 8.x // throws // after: stash or commit first $ git stash push -- changelogs/ $ ./gradlew bundleChangelogs --branch 8.x
Defensive patterns
Strategy: validation
Validate before calling
String dirty = gitRun("status", "--porcelain", changelogDir.toString()).trim();
if (dirty.isEmpty() == false) {
throw new IllegalStateException("Commit or stash changelog changes first:\n" + dirty);
} Prevention
- Always commit or stash changelog work before running bundleChangelogs.
- Run `git status` in the changelog dir as a preflight check in release scripts.
- Treat the bundling task as destructive — never run it over uncommitted work.
When it happens
Trigger: The task is about to checkout changelog YAMLs from a ref into the local changelog directory, which involves `git rm -rf <dir>` followed by `git checkout <ref> -- <dir>`. If the directory currently has uncommitted changes, those would be wiped, so the porcelain check fails fast.
Common situations: A developer has local in-progress changelog edits when running the bundling task; an untracked new changelog file was added but not committed; a previous bundling run left the directory dirty; merge conflict resolution left changelog files modified.
Related errors
- Failed to fetch branch {normalizedBranch} from {sourceRepo}
- Cannot use a commit SHA ({branchRef}) as --branch when fetch
- 'branch' not specified.
- Failed to delete some files: {files}
- Invalid tag format [{l}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/a1151ca9cf78ae42.
Report an issue: GitHub.