elastic/elasticsearch · error · InvalidUserDataException
${snippet}: Result can't be first in file
Error message
${snippet}: Result can't be first in file What it means
For a test-response snippet, after confirming previousTest is non-null, handleSnippet checks that previousTest lives in the same file as the response (previousTest.path().equals(snippet.path())). If they differ, the response is effectively the first test-related snippet in the current file with no paired request in-file, which the test runner cannot associate. The message 'Result can't be first in file' captures this cross-file orphan case.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/RestTestsFromDocSnippetTask.java:223
if (BAD_LANGUAGES.contains(snippet.language())) {
throw new InvalidUserDataException(snippet + ": Use `js` instead of `" + snippet.language() + "`.");
}
if (snippet.testSetup()) {
testSetup(snippet);
previousTest = snippet;
return;
}
if (snippet.testTearDown()) {
testTearDown(snippet);
previousTest = snippet;
return;
}
if (snippet.testResponse() || snippet.language().equals("console-result")) {
if (previousTest == null) {
throw new InvalidUserDataException(snippet + ": No paired previous test");
}
if (previousTest.path().equals(snippet.path()) == false) {
throw new InvalidUserDataException(snippet + ": Result can't be first in file");
}
response(snippet);
return;
}
if (("js".equals(snippet.language())) && snippet.console() != null && snippet.console()) {
throw new InvalidUserDataException(snippet + ": Use `[source,console]` instead of `// CONSOLE`.");
}
if (snippet.test() || snippet.language().equals("console")) {
test(snippet);
previousTest = snippet;
}
// Must be an unmarked snippet....
}
private void test(Snippet test) {
setupCurrent(test);
if (test.continued()) {View on GitHub (pinned to db6a809a66)
Solutions
- Move the paired console request snippet into the same file as the response, above it.
- If the response belongs to a request in another file, remove the orphaned response from this file.
Example fix
// file_b.asciidoc — before: response orphaned in a new file
// TESTRESPONSE
{"hits":{"total":0}}
// after: bring the request into the same file
// CONSOLE
GET /my-index/_search
// TESTRESPONSE
{"hits":{"total":0}} Defensive patterns
Strategy: validation
Validate before calling
// Ensure response snippets share the same file as their paired request
void checkResponseSameFile(List<SnippetInfo> snippets) {
String lastRequestFile = null;
for (SnippetInfo s : snippets) {
if (s.isRequest) lastRequestFile = s.filePath;
if (s.isResponse && !s.filePath.equals(lastRequestFile)) {
throw new IllegalStateException(
"Response in " + s.filePath + " pairs with request in " + lastRequestFile
+ " — they must be in the same file");
}
}
} Prevention
- Keep request and response snippets in the same doc file.
- When refactoring docs into multiple files, move request+response pairs together, never split them.
- After file splits, run the docs build immediately to catch orphaned responses.
When it happens
Trigger: A console-result/TESTRESPONSE snippet is the first test snippet encountered in a document file, but a previousTest from a different file exists (so the null check passed but the path check fails).
Common situations: Splitting one asciidoc file into two and leaving the response block in the second file while its request stayed in the first; or copy-pasting a response block into a new file without its request.
Related errors
- ${snippet}: No paired previous test
- Extra content ${message} ('${cutOutNoNl}') matching [${patte
- Didn't match ${pattern}: ${content}
- Invalid block quote starting at ${start} in: ${body}
- ${snippet}: Use `[source,console]` instead of `// CONSOLE`.
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/0829216ecf2c6510.
Report an issue: GitHub.