elastic/elasticsearch · error · ScriptException

compile error

Error message

compile error

What it means

Thrown by convertToScriptException with message "compile error" when JavascriptCompiler.compile() raises a ParseException during expression parsing. The resulting ScriptException includes the source text, a stack with a pointer to the error offset, and the original ParseException as cause. This is a syntax-level failure in the expression source string.

Source

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

        return new ExpressionScoreScript(expr, bindings, needsScores);
    }

    /**
     * converts a ParseException at compile-time or link-time to a ScriptException
     */
    private static ScriptException convertToScriptException(String message, String source, String portion, Throwable cause) {
        List<String> stack = new ArrayList<>();
        stack.add(portion);
        StringBuilder pointer = new StringBuilder();
        if (cause instanceof ParseException) {
            int offset = ((ParseException) cause).getErrorOffset();
            for (int i = 0; i < offset; i++) {
                pointer.append(' ');
            }
        }
        pointer.append("^---- HERE");
        stack.add(pointer.toString());
        throw new ScriptException(message, cause, stack, source, NAME);
    }

    private static DoubleValuesSource getDocValueSource(String variable, SearchLookup lookup) throws ParseException {
        VariableContext[] parts = VariableContext.parse(variable);
        if (parts[0].text.equals("doc") == false) {
            throw new ParseException("Unknown variable [" + parts[0].text + "]", 0);
        }
        if (parts.length < 2 || parts[1].type != VariableContext.Type.STR_INDEX) {
            throw new ParseException("Variable 'doc' must be used with a specific field like: doc['myfield']", 3);
        }

        // .value is the default for doc['field'], its optional.
        String variablename = "value";
        String methodname = null;
        if (parts.length == 3) {
            if (parts[2].type == VariableContext.Type.METHOD) {
                methodname = parts[2].text;
            } else if (parts[2].type == VariableContext.Type.MEMBER) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Check the ScriptException stack trace — it includes a '^---- HERE' pointer showing the exact character offset of the syntax error.
  2. Validate the expression syntax: expressions support only arithmetic (+, -, *, /, %, bitwise &, |, ^, shift), comparison, ternary, and function calls from DEFAULT_FUNCTIONS.
  3. Balance all parentheses and brackets; ensure string literals in doc['field'] use single quotes.

Example fix

// before: missing closing bracket
"source": "doc['price'.value * 1.2"
// after: close the bracket
"source": "doc['price'].value * 1.2"
Defensive patterns

Strategy: validation

Validate before calling

// Validate expression syntax before deployment by compiling in a test
// Expression supports: arithmetic, bitwise, comparison, ternary, and DEFAULT_FUNCTIONS
// Does NOT support: loops, if/else blocks, string ops, variable assignment
// Quick test: run a trivial query with the expression
GET my-index/_search
{ "query": { "function_score": { "script_score": { "script": { "lang": "expression", "source": "<YOUR_EXPRESSION>" } } } } }

Try / catch

// When compiling expressions programmatically:
try {
    engine.compile(scriptName, scriptSource, context, params);
} catch (ScriptException e) {
    if ("compile error".equals(e.getScriptStack().get(0)) || e.getMessage().contains("compile error")) {
        // Syntax error — check the ^--- HERE pointer in the stack
        logger.error("Expression syntax error at offset: {}", e.getScriptStack());
    }
    throw e;
}

Prevention

When it happens

Trigger: Submitting an expression script with invalid JavaScript-like syntax — e.g., unbalanced parentheses, unknown operators, invalid variable names, or malformed function calls. Example: "doc['price'.value" (missing bracket) or "doc['price'] ++ value" (invalid operator).

Common situations: Typos in expression source; copy-paste errors; dynamically generated expressions with unescaped user input; attempting to use syntax features not supported by Lucene's expression compiler (no loops, no conditionals, no string operations).

Related errors


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