elastic/elasticsearch · error · InvalidUserDataException
Invalid json in {name}. The error is: {errorMessage}. After
Error message
Invalid json in {name}. The error is:
{errorMessage}.
After substitutions and munging, the json looks like:
{quoted} What it means
Thrown by SnippetBuilder.assertValidJsonInput() when a snippet marked for response testing (TESTRESPONSE) in `js` or `console-result` language fails to parse as JSON after the doc framework applies its variable substitution/munging. The framework quotes `$`-prefixed values and fields, enables lenient backslash escaping, then runs the Jackson parser end-to-end; a JsonParseException is rethrown with the original parser message plus the post-substitution text so the author can see exactly what failed.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/SnippetBuilder.java:249
private void assertValidJsonInput(String content) {
if (testResponse && ("js" == language || "console-result" == language) && null == skip) {
String quoted = content
// quote values starting with $
.replaceAll("([:,])\\s*(\\$[^ ,\\n}]+)", "$1 \"$2\"")
// quote fields starting with $
.replaceAll("(\\$[^ ,\\n}]+)\\s*:", "\"$1\":");
JsonFactory jf = new JsonFactory();
jf.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
JsonParser jsonParser;
try {
jsonParser = jf.createParser(quoted);
while (jsonParser.isClosed() == false) {
jsonParser.nextToken();
}
} catch (JsonParseException e) {
throw new InvalidUserDataException(
"Invalid json in "
+ name
+ ". The error is:\n"
+ e.getMessage()
+ ".\n"
+ "After substitutions and munging, the json looks like:\n"
+ quoted,
e
);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public SnippetBuilder withConsole(Boolean console) {
this.console = console;
return this;View on GitHub (pinned to db6a809a66)
Solutions
- Copy the 'After substitutions and munging' JSON from the error message and paste it into a JSON linter to find the exact syntax error.
- Fix the source snippet so the post-substitution result is valid JSON (balance braces, remove trailing commas, quote non-`$` keys).
- If the failure is a substitution artifact, adjust how the `$variable` is placed so the auto-quoting regex matches it (it expects `$`-tokens at value or field positions, not embedded inside other tokens).
- For genuinely non-JSON content use the `non_json` TESTRESPONSE modifier instead of trying to make it parse.
Example fix
// before:
// TESTRESPONSE
{ "hits": { "total": 42, } } // trailing comma
// after:
// TESTRESPONSE
{ "hits": { "total": 42 } } Defensive patterns
Strategy: try-catch
Validate before calling
// Before building, run the snippet's post-substitution JSON through a parser: // String quoted = applySubstitutions(content); JsonParser p = jf.createParser(quoted); // while (!p.isClosed()) p.nextToken(); // throws on invalid JSON
Try / catch
// try (JsonParser p = jf.createParser(quoted)) { while (!p.isClosed()) p.nextToken(); }
// catch (JsonParseException e) { /* report snippet name + quoted text + e.getMessage() */ } Prevention
- Validate every TESTRESPONSE snippet's JSON in a linter before committing.
- Place `$variable` placeholders at value/field boundaries the auto-quoting regex expects.
- Use the `non_json` TESTRESPONSE modifier for genuinely non-JSON responses instead of fighting the parser.
- Avoid trailing commas and unquoted non-`$` keys.
When it happens
Trigger: A `// TESTRESPONSE` snippet in js/console-result contains JSON that is malformed even after the framework's `$variable` quoting substitutions. Triggers on: unbalanced braces/brackets, trailing commas, unquoted keys (other than `$`-prefixed ones the regex handles), invalid escape sequences beyond the lenient mode, or a substitution that produces invalid JSON.
Common situations: A response example has a hand-edited typo; a `$variable` placeholder is placed where the auto-quoting regex does not apply (e.g. mid-token rather than at a value/field boundary); the snippet was converted from a non-JSON format and kept invalid syntax; an escape like `\x` that Jackson's ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER still rejects.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unexpected unconverted snippets: {foundButNotListed}
- Couldn't find the corresponding mdx file for {asciidocFileAb
- Yaml rest specs ({asciidocFile} and {mdxFile}) are not equal
- Yaml rest specs ({asciidocFile} and {mdxFile}) are not equal
- {name}: Snippet missing a language. This is required by Elas
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/40923c8b285fa262.
Report an issue: GitHub.