elastic/elasticsearch · error · ParseException

Variable 'doc' must be used with a specific field like: doc[

Error message

Variable 'doc' must be used with a specific field like: doc['myfield']

What it means

Thrown in getDocValueSource() when the variable starts with 'doc' but the second segment is not a string-indexed field name (i.e., not in the form doc['fieldname']). The parser expects VariableContext.Type.STR_INDEX for the field specifier, which means bracket notation with a quoted string.

Source

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

        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) {
                variablename = parts[2].text;
            } else {
                throw new IllegalArgumentException(
                    "Only member variables or member methods may be accessed on a field when not accessing the field directly"
                );
            }
        }
        // true if the variable is of type doc['field'].date.xxx
        boolean dateAccessor = false;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use bracket notation with single quotes: doc['myfield'] not doc.myfield.
  2. Ensure the field name is enclosed in single quotes inside the brackets.
  3. For method access on fields, use doc['myfield'].value or doc['myfield'].methodName() — the field itself is always bracket-accessed.

Example fix

// before: dot notation is not valid in expressions
"source": "doc.price.value"
// after: bracket notation with single quotes
"source": "doc['price'].value"
Defensive patterns

Strategy: validation

Validate before calling

// Validate that field access uses bracket notation with single quotes
// Correct: doc['fieldname']
// Incorrect: doc.fieldname, doc["fieldname"], doc[fieldname]
// Simple regex check:
// Pattern: doc\['[\w.]+'\]
String exprSource = "doc['price'].value";
if (!exprSource.matches(".*doc\['[^']+'\].*")) {
    // Warn: field access should use doc['fieldname'] syntax
}

Try / catch

try {
    engine.compile(scriptName, scriptSource, context, params);
} catch (ScriptException e) {
    if (e.getCause() instanceof ParseException
        && e.getCause().getMessage().contains("must be used with a specific field")) {
        logger.error("Use doc['fieldname'] bracket notation, not dot notation");
    }
    throw e;
}

Prevention

When it happens

Trigger: Using 'doc' without bracket-notation field access — e.g., doc.price (dot notation), doc (bare), or doc[price] (unquoted). The expression engine requires doc['fieldname'] syntax specifically.

Common situations: Developers familiar with Painless syntax attempting dot-notation access (doc.price) in expressions; missing quotes around the field name; copy-paste from Painless examples.

Related errors


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