elastic/elasticsearch · error · InvalidUserDataException

{name}: No need for NOTCONSOLE if snippet doesn't contain `c

Error message

{name}: No need for NOTCONSOLE if snippet doesn't contain `curl`.

What it means

Thrown by SnippetBuilder.assertValidCurlInput() when a snippet is tagged `NOTCONSOLE` (i.e. `console = false`) but its language is `sh`/`shell` AND the snippet body does not contain the text `curl`. The NOTCONSOLE marker only makes sense for shell snippets that would otherwise be treated as console examples because they contain `curl`; a non-curl shell snippet has no reason to be marked NOTCONSOLE, so the build flags it as a contradictory/misleading annotation.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/doc/SnippetBuilder.java:226

                name
                    + ": "
                    + "Snippet missing a language. This is required by "
                    + "Elasticsearch's doc testing infrastructure so we "
                    + "be sure we don't accidentally forget to test a "
                    + "snippet."
            );
        }
        assertValidCurlInput(content);
        assertValidJsonInput(content);

    }

    private void assertValidCurlInput(String content) {
        // Try to detect snippets that contain `curl`
        if ("sh".equals(language) || "shell".equals(language)) {
            curl = content.contains("curl");
            if (console == Boolean.FALSE && curl == false) {
                throw new InvalidUserDataException(name + ": " + "No need for NOTCONSOLE if snippet doesn't " + "contain `curl`.");
            }
        }
    }

    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);

View on GitHub (pinned to db6a809a66)

Solutions

  1. Remove the `// NOTCONSOLE` directive from the snippet — it is unnecessary for a non-curl shell snippet.
  2. If the snippet was meant to contain a curl command, add the curl invocation back to the snippet body.
  3. Double-check the language is genuinely `sh`/`shell`; if it is a different language the NOTCONSOLE marker is also irrelevant and should be removed.

Example fix

// before:
// NOTCONSOLE
----
echo hello
----
// after:
----
echo hello
----
Defensive patterns

Strategy: validation

Validate before calling

// Before building, for sh/shell snippets check:
// if ("sh".equals(lang) || "shell".equals(lang)) {
//   boolean hasCurl = content.contains("curl");
//   if (console==Boolean.FALSE && !hasCurl) fail("NOTCONSOLE without curl");
// }

Prevention

When it happens

Trigger: A doc snippet has language `sh` or `shell`, includes a `// NOTCONSOLE` directive, but the snippet text does not include the substring `curl`. The validation logic sets `curl = content.contains("curl")` and then checks `console == FALSE && curl == false`.

Common situations: A contributor adds `// NOTCONSOLE` defensively or by copy-paste to a plain shell snippet that never had a curl command; a snippet's curl command was removed but the NOTCONSOLE marker was left behind.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/f658c5b330886095. Report an issue: GitHub.