elastic/elasticsearch · error · IllegalArgumentException

Only member variables or member methods may be accessed on a

Error message

Only member variables or member methods may be accessed on a field when not accessing the field directly

What it means

Thrown in getDocValueSource() when the variable has exactly 3 parts (doc['field'].something) but the third part is neither a METHOD nor MEMBER type in the parsed VariableContext. This covers unusual parsing artifacts — e.g., a numeric index or other non-standard access pattern after the field bracket.

Source

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

    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;
        if (parts.length > 3) {
            // access to the .date "object" within the field
            if (parts.length == 4 && ("date".equals(parts[2].text) || "getDate".equals(parts[2].text))) {
                if (parts[3].type == VariableContext.Type.METHOD) {
                    methodname = parts[3].text;
                    dateAccessor = true;
                } else if (parts[3].type == VariableContext.Type.MEMBER) {
                    variablename = parts[3].text;
                    dateAccessor = true;
                }
            }
            if (dateAccessor == false) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use only member access (doc['field'].value, doc['field'].lat) or method calls (doc['field'].abs()) after the field bracket.
  2. Remove any numeric index or non-standard accessor after doc['field'].
  3. If you need array/multi-value access, note that expression scripts only return the first value — use Painless for multi-value logic.

Example fix

// before: invalid accessor type after field
"source": "doc['tags'][0]"
// after: use .value for the first value (expressions only support single values)
"source": "doc['tags'].value"
Defensive patterns

Strategy: validation

Validate before calling

// Validate that field accessors after doc['field'] are only .member or .method()
// Correct: doc['field'].value, doc['field'].lat, doc['field'].abs()
// Incorrect: doc['field'][0], doc['field']['sub']
// Check expression source for unsupported accessor patterns

Try / catch

try {
    engine.compile(scriptName, scriptSource, context, params);
} catch (ScriptException e) {
    if (e.getCause() instanceof IllegalArgumentException
        && e.getCause().getMessage().contains("Only member variables or member methods")) {
        logger.error("Use only .value or .method() after doc['field'] — no array indexing");
    }
    throw e;
}

Prevention

When it happens

Trigger: An expression uses a syntax like doc['field'][0] (array indexing) or some other non-member, non-method access after the field bracket. The expression parser classifies segments as STR_INDEX, MEMBER, METHOD, or CLASS — this error fires when the third segment is STR_INDEX in an unexpected position.

Common situations: Attempting array-style indexing on a field; malformed expression where a bracket or parenthesis is misplaced; edge cases in VariableContext.parse producing unexpected segment types.

Related errors


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