elastic/elasticsearch · error · UnsupportedOperationException

unsupported script context name [{}]

Error message

unsupported script context name [{}]

What it means

PainlessExecuteAction.fromScriptContextName looks up the requested context in the static SUPPORTED_CONTEXTS map (PainlessTestScript, FilterScript, ScoreScript, plus ScriptModule.RUNTIME_FIELDS_CONTEXTS). If the name is absent it throws UnsupportedOperationException — note this is UnsupportedOperationException, not IllegalArgumentException, distinguishing it from error 1350. The name is interpolated.

Source

Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java:164

        }

        private static Map<String, ScriptContext<?>> getSupportedContexts() {
            Map<String, ScriptContext<?>> contexts = new HashMap<>();
            contexts.put(PainlessTestScript.CONTEXT.name, PainlessTestScript.CONTEXT);
            contexts.put(FilterScript.CONTEXT.name, FilterScript.CONTEXT);
            contexts.put(ScoreScript.CONTEXT.name, ScoreScript.CONTEXT);
            for (ScriptContext<?> runtimeFieldsContext : ScriptModule.RUNTIME_FIELDS_CONTEXTS) {
                contexts.put(runtimeFieldsContext.name, runtimeFieldsContext);
            }
            return Collections.unmodifiableMap(contexts);
        }

        static final Map<String, ScriptContext<?>> SUPPORTED_CONTEXTS = getSupportedContexts();

        static ScriptContext<?> fromScriptContextName(String name) {
            ScriptContext<?> scriptContext = SUPPORTED_CONTEXTS.get(name);
            if (scriptContext == null) {
                throw new UnsupportedOperationException("unsupported script context name [" + name + "]");
            }
            return scriptContext;
        }

        static class ContextSetup implements Writeable, ToXContentObject {

            private static final ParseField INDEX_FIELD = new ParseField("index");
            private static final ParseField DOCUMENT_FIELD = new ParseField("document");
            private static final ParseField QUERY_FIELD = new ParseField("query");
            private static final ConstructingObjectParser<ContextSetup, Void> PARSER = new ConstructingObjectParser<>(
                "execute_script_context",
                args -> new ContextSetup((String) args[0], (BytesReference) args[1], (QueryBuilder) args[2])
            );

            static {
                PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), INDEX_FIELD);
                PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> {
                    try (XContentBuilder b = XContentBuilder.builder(p.contentType().xContent())) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use one of the supported execute contexts: 'painless_test', 'filter', 'score', or a runtime-field context name.
  2. For other contexts, test the script through its native endpoint (e.g. _ingest/pipeline/_simulate, _update_by_query) instead of _execute.
  3. List valid names by inspecting SUPPORTED_CONTEXTS keys or the Painless execute docs for your ES version.

Example fix

// before
POST /_scripts/painless/_execute
{ "script": {...}, "context": "ingest" } // not supported -> 1351
// after
POST /_scripts/painless/_execute
{ "script": {...}, "context": "filter", "context_setup": {...} }
Defensive patterns

Strategy: validation

Validate before calling

static final Set<String> EXECUTABLE = Set.of("painless_test", "filter", "score");
void assertExecutableContext(String name) {
    if (!EXECUTABLE.contains(name) && !name.startsWith("bool_field") && !name.endsWith("_field"))
        throw new UnsupportedOperationException("context not executable via _execute: " + name);
}

Try / catch

try {
    client.execute(PainlessExecuteAction.INSTANCE, request);
} catch (UnsupportedOperationException e) {
    if (e.getMessage().startsWith("unsupported script context name")) {
        // switch to a native endpoint (_ingest/pipeline/_simulate, _update_by_query) for that context
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling POST /_scripts/painless/_execute with a 'context' field set to a name not in the execute API's fixed allowlist — e.g. an ingest or update context name, or a custom plugin context, none of which are supported by the standalone _execute endpoint.

Common situations: Trying to test an ingest-style script via the _execute API; using a context name valid elsewhere (aggregation, update) but unsupported here; version differences in runtime-field context names.

Related errors


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