elastic/elasticsearch · error · IllegalArgumentException
Illegal list shortcut value [{}].
Error message
Illegal list shortcut value [{}]. What it means
Def.lookupGetter handles dynamic field reads on 'def'. For a List receiver, the field name must be an integer index (lists allow mylist.0 syntax). The code Integer.parseInt(name) and throws 'Illegal list shortcut value [name]' on NumberFormatException if the name is not parseable as an integer — e.g. mylist.foo where 'foo' is non-numeric.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java:658
}
// special case: arrays, maps, and lists
if (receiverClass.isArray() && "length".equals(name)) {
// arrays expose .length as a read-only getter
return arrayLengthGetter(receiverClass);
} else if (Map.class.isAssignableFrom(receiverClass)) {
// maps allow access like mymap.key
// wire 'key' as a parameter, its a constant in painless
return MethodHandles.insertArguments(MAP_GET, 1, name);
} else if (List.class.isAssignableFrom(receiverClass)) {
// lists allow access like mylist.0
// wire '0' (index) as a parameter, its a constant. this also avoids
// parsing the same integer millions of times!
try {
int index = Integer.parseInt(name);
return MethodHandles.insertArguments(LIST_GET, 1, index);
} catch (NumberFormatException exception) {
throw new IllegalArgumentException("Illegal list shortcut value [" + name + "].");
}
}
throw new IllegalArgumentException("dynamic getter [" + typeToCanonicalTypeName(receiverClass) + ", " + name + "] not found");
}
/**
* Looks up handle for a dynamic field setter (field store)
* <p>
* A dynamic field store for variable {@code x} of type {@code def} looks like:
* {@code x.field = y}
* <p>
* The following field stores are allowed:
* <ul>
* <li>Whitelisted {@code field} from receiver's class or any superclasses.
* <li>Whitelisted method named {@code setField()} from receiver's class/superclasses/interfaces.
* <li>The value corresponding to a map key named {@code field} when the receiver is a Map.
* <li>The value in a list at element {@code field} (integer) when the receiver is a List.View on GitHub (pinned to db6a809a66)
Solutions
- Use an integer index for List access: mylist.0 or mylist[0].
- If named access is intended, ensure the receiver is a Map, not a List.
- Bracket access (mylist[i]) is preferred for dynamic indices.
Example fix
// before def x = [10, 20, 30]; return x.first; // non-numeric shortcut on a List // after return x[0];
Defensive patterns
Strategy: type-guard
Type guard
// Guard List dot-access: only allow if name is an integer string
function safeListGet(list, name) {
if (!/^-?\d+$/.test(String(name))) throw new Error(`Use integer index for List; got '${name}'`);
return list[Number(name)];
} Try / catch
// Surface 'Illegal list shortcut value' to the script author with guidance to use bracket indexing.
Prevention
- Use bracket syntax mylist[i] for List element access.
- Reserve dot-access for Maps with string keys.
- Static-type collections to catch confusion at compile time.
When it happens
Trigger: A Painless script reads a List via dot-shortcut with a non-integer name: def x = [1,2,3]; x.first or x.foo. Maps allow arbitrary string keys (mymap.key), but Lists require integer indices (mylist.0).
Common situations: Treating a List like a Map (expecting named access). Confusing list element access patterns. Runtime type of the variable being List when the author assumed Map.
Related errors
- Illegal list shortcut value [name].
- dynamic method [{}, {}/{}] not found
- dynamic getter [{}, {}] not found
- dynamic setter [receiverClass, name] not found
- Attempting to address a non-array-like type [receiverClass]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/a1a0e45614237076.
Report an issue: GitHub.