elastic/elasticsearch · error · InvalidUserDataException
Found multiple files with the same name '${fileNameWithoutEx
Error message
Found multiple files with the same name '${fileNameWithoutExt}' but different extensions: [asciidoc, mdx] What it means
setupCurrent calls hasMultipleDocImplementations, which returns true when both a '.asciidoc' and a '.mdx' version of the same path exist in the docs dir. If migration mode is OFF (the default), having both formats is ambiguous (which one generates the test?) and the task throws. Migration mode is a temporary flag used while converting docs from asciidoc to mdx; it allows generating from both and asserts equality.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/RestTestsFromDocSnippetTask.java:429
private PrintWriter setupCurrent(Snippet test) {
if (test.path().equals(lastDocsPath)) {
return current;
}
names.clear();
finishLastTest();
lastDocsPath = test.path();
// Make the destination file:
// Shift the path into the destination directory tree
Path dest = getOutputRoot().toPath().resolve(test.path());
// Replace the extension
String fileName = dest.getName(dest.getNameCount() - 1).toString();
if (hasMultipleDocImplementations(test.path())) {
String fileNameWithoutExt = dest.getName(dest.getNameCount() - 1).toString().replace(".asciidoc", "").replace(".mdx", "");
if (getMigrationMode().get() == false) {
throw new InvalidUserDataException(
"Found multiple files with the same name '" + fileNameWithoutExt + "' but different extensions: [asciidoc, mdx]"
);
}
getLogger().warn("Found multiple doc file types for " + test.path() + ". Generating tests for all of them.");
dest = dest.getParent().resolve(fileName + ".yml");
} else {
dest = dest.getParent().resolve(fileName.replace(".asciidoc", ".yml").replace(".mdx", ".yml"));
}
// Now setup the writer
try {
Files.createDirectories(dest.getParent());
current = new PrintWriter(dest.toFile(), StandardCharsets.UTF_8);
return current;
} catch (IOException e) {
throw new RuntimeException(e);View on GitHub (pinned to db6a809a66)
Solutions
- Delete one of the duplicate files (keep either the asciidoc or the mdx, not both).
- If you are actively migrating, enable migration mode on the task: restTestsTask.getMigrationMode().set(true) — this generates from both and compares them.
- Exclude one extension from the docs FileTree so only one format is processed.
Example fix
// before — both files exist; migration mode off // docs/guide/search.asciidoc AND docs/guide/search.mdx restTestsTask.getMigrationMode().set(false) // after — option A: remove one file rm docs/guide/search.asciidoc // after — option B: enable migration mode restTestsTask.getMigrationMode().set(true)
Defensive patterns
Strategy: validation
Validate before calling
// Detect duplicate asciidoc/mdx file pairs before building
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
List<String> findDuplicateDocPairs(File docsDir) throws java.io.IOException {
List<String> dups = new ArrayList<>();
try (var s = Files.walk(docsDir.toPath())) {
var asciidocs = s.filter(p -> p.toString().endsWith(".asciidoc")).toList();
for (Path a : asciidocs) {
Path m = Path.of(a.toString().replace(".asciidoc", ".mdx"));
if (Files.exists(m)) dups.add(a.getFileName().toString());
}
}
return dups;
}
// if !dups.isEmpty() && !migrationMode: fail with the duplicate list Prevention
- Keep only one format (.asciidoc OR .mdx) per document path unless migration mode is on.
- When creating an mdx version, remove the asciidoc original (or enable migration mode temporarily).
- Run a duplicate-pair detection script in CI before the docs build.
When it happens
Trigger: A docs directory contains both 'guide/search.asciidoc' and 'guide/search.mdx' (same relative path, different extension), and the RestTestsFromDocSnippetTask is not in migration mode.
Common situations: During a partial asciidoc-to-mdx migration where both files coexist; accidentally creating an mdx copy without removing the asciidoc original; enabling the docs set to include both trees.
Related errors
- Unsupported file type: ${docFileName}
- ${snippet}: Use `js` instead of `${snippetLanguage}`.
- Expected unconverted snippets but none found in: {listedButN
- Couldn't find named teardown $name for ${snippet}
- Couldn't find named setup {name} for {snippet}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/f04f463a18d0b67d.
Report an issue: GitHub.