{"record":{"id":"f04f463a18d0b67d","repo":"elastic/elasticsearch","slug":"found-multiple-files-with-the-same-name-filenam","errorCode":null,"errorMessage":"Found multiple files with the same name '${fileNameWithoutExt}' but different extensions: [asciidoc, mdx]","messagePattern":"Found multiple files with the same name '(.+?)' but different extensions: \\[asciidoc, mdx\\]","errorType":"validation","errorClass":"InvalidUserDataException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/RestTestsFromDocSnippetTask.java","lineNumber":429,"sourceCode":"\n        private PrintWriter setupCurrent(Snippet test) {\n            if (test.path().equals(lastDocsPath)) {\n                return current;\n            }\n            names.clear();\n            finishLastTest();\n            lastDocsPath = test.path();\n\n            // Make the destination file:\n            // Shift the path into the destination directory tree\n            Path dest = getOutputRoot().toPath().resolve(test.path());\n            // Replace the extension\n            String fileName = dest.getName(dest.getNameCount() - 1).toString();\n            if (hasMultipleDocImplementations(test.path())) {\n                String fileNameWithoutExt = dest.getName(dest.getNameCount() - 1).toString().replace(\".asciidoc\", \"\").replace(\".mdx\", \"\");\n\n                if (getMigrationMode().get() == false) {\n                    throw new InvalidUserDataException(\n                        \"Found multiple files with the same name '\" + fileNameWithoutExt + \"' but different extensions: [asciidoc, mdx]\"\n                    );\n                }\n                getLogger().warn(\"Found multiple doc file types for \" + test.path() + \". Generating tests for all of them.\");\n                dest = dest.getParent().resolve(fileName + \".yml\");\n\n            } else {\n                dest = dest.getParent().resolve(fileName.replace(\".asciidoc\", \".yml\").replace(\".mdx\", \".yml\"));\n\n            }\n\n            // Now setup the writer\n            try {\n                Files.createDirectories(dest.getParent());\n                current = new PrintWriter(dest.toFile(), StandardCharsets.UTF_8);\n                return current;\n            } catch (IOException e) {\n                throw new RuntimeException(e);","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/RestTestsFromDocSnippetTask.java#L411-L447","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — both files exist; migration mode off\n// docs/guide/search.asciidoc  AND  docs/guide/search.mdx\nrestTestsTask.getMigrationMode().set(false)\n\n// after — option A: remove one file\nrm docs/guide/search.asciidoc\n// after — option B: enable migration mode\nrestTestsTask.getMigrationMode().set(true)","handlingStrategy":"validation","validationCode":"// Detect duplicate asciidoc/mdx file pairs before building\nimport java.io.File;\nimport java.nio.file.Path;\nimport java.nio.file.Files;\nimport java.util.ArrayList;\nimport java.util.List;\n\nList<String> findDuplicateDocPairs(File docsDir) throws java.io.IOException {\n    List<String> dups = new ArrayList<>();\n    try (var s = Files.walk(docsDir.toPath())) {\n        var asciidocs = s.filter(p -> p.toString().endsWith(\".asciidoc\")).toList();\n        for (Path a : asciidocs) {\n            Path m = Path.of(a.toString().replace(\".asciidoc\", \".mdx\"));\n            if (Files.exists(m)) dups.add(a.getFileName().toString());\n        }\n    }\n    return dups;\n}\n// if !dups.isEmpty() && !migrationMode: fail with the duplicate list","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["docs","migration","asciidoc","mdx","duplicate","gradle"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}