elastic/elasticsearch · error · IllegalArgumentException

expression engine does not know how to handle script context

Error message

expression engine does not know how to handle script context [{}]

What it means

Thrown in ExpressionScriptEngine.compile() when the requested ScriptContext is not in the supported contexts map. The expression engine only supports a fixed set of contexts: BucketAggregationScript, BucketAggregationSelectorScript, FilterScript, ScoreScript, TermsSetQueryScript, AggregationScript, NumberSortScript, FieldScript, and DoubleValuesScript. Any other context (e.g., ingest processor, update script, bulk ingest) is rejected at compile time.

Source

Thrown at modules/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionScriptEngine.java:164

        }
    );

    @Override
    public String getType() {
        return NAME;
    }

    @Override
    public <T> T compile(String scriptName, String scriptSource, ScriptContext<T> context, Map<String, String> params) {
        Expression expr;
        try {
            // NOTE: validation is delayed to allow runtime vars, and we don't have access to per index stuff here
            expr = JavascriptCompiler.compile(scriptSource, JavascriptCompiler.DEFAULT_FUNCTIONS);
        } catch (ParseException e) {
            throw convertToScriptException("compile error", scriptSource, scriptSource, e);
        }
        if (contexts.containsKey(context) == false) {
            throw new IllegalArgumentException("expression engine does not know how to handle script context [" + context.name + "]");
        }
        return context.factoryClazz.cast(contexts.get(context).apply(expr));
    }

    @Override
    public Set<ScriptContext<?>> getSupportedContexts() {
        return contexts.keySet();
    }

    private static BucketAggregationScript.Factory newBucketAggregationScriptFactory(Expression expr) {
        return parameters -> {
            ReplaceableConstDoubleValues[] functionValuesArray = new ReplaceableConstDoubleValues[expr.variables.length];
            Map<String, ReplaceableConstDoubleValues> functionValuesMap = new HashMap<>();
            for (int i = 0; i < expr.variables.length; ++i) {
                functionValuesArray[i] = new ReplaceableConstDoubleValues();
                functionValuesMap.put(expr.variables[i], functionValuesArray[i]);
            }
            return new BucketAggregationScript(parameters) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Switch to Painless ("lang":"painless") for unsupported contexts like ingest, update, or watcher scripts.
  2. Verify the context is supported by checking ExpressionScriptEngine.getSupportedContexts().
  3. Relocate the expression logic to a supported context: e.g., move computation from an ingest processor to a runtime field or script_score query.
  4. Review the Elasticsearch expression documentation to confirm which APIs accept expression scripts.

Example fix

// before: expression in ingest pipeline (unsupported)
PUT _ingest/pipeline/my-pipeline
{
  "processors": [{
    "script": { "lang": "expression", "source": "doc['price'].value * 1.2" }
  }]
}
// after: use painless for ingest
PUT _ingest/pipeline/my-pipeline
{
  "processors": [{
    "script": { "lang": "painless", "source": "ctx.price *= 1.2" }
  }]
}
Defensive patterns

Strategy: validation

Validate before calling

// Before compiling an expression script, verify the context is supported
Set<ScriptContext<?>> supported = ExpressionScriptEngine.getSupportedContexts();
// Or via REST: expression scripts only work in these contexts:
//   function_score / script_score, runtime fields, sort, 
//   bucket_script / bucket_selector aggregations, terms_set query
// Do NOT use in: ingest pipelines, update scripts, watcher actions

Try / catch

// In plugin code, check supported contexts before compiling:
if (engine.getSupportedContexts().contains(targetContext) == false) {
    throw new IllegalArgumentException(
        "Expression engine does not support context " + targetContext + ". Use Painless instead."
    );
}
engine.compile(scriptName, scriptSource, targetContext, params);

Prevention

When it happens

Trigger: Submitting an expression script in a context the engine does not support — for example, using "lang":"expression" in an ingest pipeline processor, an update by query script, or any context whose ScriptContext is not registered in the contexts map at line 56-147.

Common situations: Migrating from Painless to expression for performance without realizing expression only supports read-time numeric contexts; trying to use expression in an ingest pipeline or update script.

Related errors


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