elastic/elasticsearch · error · InvalidUserDataException
Didn't match ${pattern}: ${content}
Error message
Didn't match ${pattern}: ${content} What it means
ParsingUtils.parse compiles the pattern against the content and enters the match loop. If offset stays 0 after the loop, no match was found at all — the entire snippet content failed to match the CONSOLE syntax grammar even once. This is distinct from extra_content (partial match) because here the regex matched nothing.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/ParsingUtils.java:49
* matchers each time there is a match. If there are characters that don't
* match then blow up. If the closure takes two parameters then the second
* one is "is this the last match?".
*/
static void parse(String content, String pattern, BiConsumer<Matcher, Boolean> testHandler) {
if (content == null) {
return; // Silly null, only real stuff gets to match!
}
Matcher m = Pattern.compile(pattern).matcher(content);
int offset = 0;
while (m.find()) {
if (m.start() != offset) {
extraContent("between [$offset] and [${m.start()}]", content, offset, pattern);
}
offset = m.end();
testHandler.accept(m, offset == content.length());
}
if (offset == 0) {
throw new InvalidUserDataException("Didn't match " + pattern + ": " + content);
}
if (offset != content.length()) {
extraContent("after [" + offset + "]", content, offset, pattern);
}
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Check the content shown in the message and add at least one valid request line (e.g. 'GET /_search').
- If the snippet should be empty/non-executable, mark it with the appropriate snippet attribute (e.g. // NOTCONSOLE) instead of leaving it as a console test.
- Verify the snippet opening delimiter in the asciidoc/mdx source is correct so content is actually captured.
Example fix
// before — empty console snippet produces no match // CONSOLE // after — add a valid request // CONSOLE GET /_cluster/health
Defensive patterns
Strategy: validation
Validate before calling
// Ensure every console snippet has at least one parseable request
import java.util.regex.Pattern;
private static final Pattern HAS_REQUEST = Pattern.compile(
"(GET|PUT|POST|HEAD|OPTIONS|DELETE)\\s+\\S+|#|startyaml");
void checkNonEmptyConsole(String contents, String snippetPath) {
if (!HAS_REQUEST.matcher(contents).find()) {
throw new IllegalStateException(
"Console snippet in " + snippetPath + " has no valid request, comment, or yaml block: "
+ contents);
}
} Prevention
- Never leave a // CONSOLE snippet body empty.
- If a snippet is illustrative/non-executable, mark it // NOTCONSOLE instead of // CONSOLE.
- Verify snippet delimiters in asciidoc/mdx source are correctly placed so content is captured.
When it happens
Trigger: A snippet marked as a test (// CONSOLE or console language) has a body that contains zero valid HTTP request lines, comments, or yaml blocks — e.g. an empty snippet body, or a body containing only text that none of the method/path/yaml/comment alternatives can match.
Common situations: An empty console snippet, a snippet where the opening line uses a method not in the allowed set (GET|PUT|POST|HEAD|OPTIONS|DELETE), or a snippet whose content was accidentally cleared during editing.
Related errors
- Extra content ${message} ('${cutOutNoNl}') matching [${patte
- Invalid block quote starting at ${start} in: ${body}
- ${snippet}: No paired previous test
- ${snippet}: Result can't be first in file
- ${snippet}: Use `[source,console]` instead of `// CONSOLE`.
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/71764842fbd67d07.
Report an issue: GitHub.