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
- Check the ScriptException stack trace — it includes a '^---- HERE' pointer showing the exact character offset of the syntax error.
- Validate the expression syntax: expressions support only arithmetic (+, -, *, /, %, bitwise &, |, ^, shift), comparison, ternary, and function calls from DEFAULT_FUNCTIONS.
- 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
- Always test expression syntax in a non-production index before deployment.
- Use the ^---- HERE pointer in the ScriptException stack to locate syntax errors quickly.
- Remember expression syntax is a restricted subset — no loops, conditionals (beyond ternary), or string operations.
- Validate dynamically generated expressions with a linting step before submitting them.
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
- link error
- Can't advance to doc using {}
- Error evaluating {}
- Can't advance to doc using {}
- Error evaluating {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/34fcfd5abafd9652.
Report an issue: GitHub.