elastic/elasticsearch · error · IllegalArgumentException
Attempting to address a non-array type [receiverClass] as an
Error message
Attempting to address a non-array type [receiverClass] as an array.
What it means
Def.lookupArrayStore returns the array-store handle for bracket assignment x[i] = v. It handles arrays (arrayElementSetter), Maps (MAP_PUT), and Lists (LIST_SET). For any other receiverClass it throws 'Attempting to address a non-array type [...] as an array'. This is the store-side counterpart to lookupIndexNormalize/lookupArrayLoad and fires when the receiver cannot receive a bracket-store at all.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java:753
);
}
/**
* Returns a method handle to do an array store.
* @param receiverClass Class of the array to store the value in
* @return a MethodHandle that accepts the receiver as first argument, the index as second argument,
* and the value to set as 3rd argument. Return value is undefined and should be ignored.
*/
static MethodHandle lookupArrayStore(Class<?> receiverClass) {
if (receiverClass.isArray()) {
return MethodHandles.arrayElementSetter(receiverClass);
} else if (Map.class.isAssignableFrom(receiverClass)) {
// maps allow access like mymap[key]
return MAP_PUT;
} else if (List.class.isAssignableFrom(receiverClass)) {
return LIST_SET;
}
throw new IllegalArgumentException(
"Attempting to address a non-array type " + "[" + receiverClass.getCanonicalName() + "] as an array."
);
}
/**
* Returns a method handle to do an array load.
* @param receiverClass Class of the array to load the value from
* @return a MethodHandle that accepts the receiver as first argument, the index as second argument.
* It returns the loaded value.
*/
static MethodHandle lookupArrayLoad(Class<?> receiverClass) {
if (receiverClass.isArray()) {
return MethodHandles.arrayElementGetter(receiverClass);
} else if (Map.class.isAssignableFrom(receiverClass)) {
// maps allow access like mymap[key]
return MAP_GET;
} else if (List.class.isAssignableFrom(receiverClass)) {
return LIST_GET;View on GitHub (pinned to db6a809a66)
Solutions
- Confirm the receiver is a mutable array, List, or Map before bracket assignment.
- Use a List/Map from params or ctx for accumulation, not scalar variables.
- Type the receiver concretely to get compile-time validation.
- For source updates in update-by-query, write to ctx._source (a Map) instead of doc fields.
Example fix
// before def n = 5; n[0] = 1; // scalar is not array-storable // after def arr = new int[1]; arr[0] = 1;
Defensive patterns
Strategy: type-guard
Type guard
// Before bracket-assign on a def value, confirm it is a mutable array/List/Map
function isMutableContainer(v) {
return Array.isArray(v) || v instanceof Map || (v && typeof v.length === 'number');
}
// if (!isMutableContainer(x)) throw new Error('Cannot store into non-container'); Try / catch
// On 'Attempting to address a non-array type', tell the author the receiver is a scalar/immutable and to use a List/Map/ctx._source.
Prevention
- Allocate a List/array/Map for accumulation; don't assign into scalars.
- For source updates, write to ctx._source, not doc fields.
- Static-type mutable buffers to catch errors at compile time.
When it happens
Trigger: A Painless script writes x[i] = value where x is a 'def' whose runtime class is not an array, Map, or List — e.g. assigning into a String, a number, or a scalar wrapper.
Common situations: Treating a scalar as a container. Receiver resolved to an immutable type. Mistaking a wrapper for a collection. Trying to mutate doc values via bracket assignment.
Related errors
- Attempting to address a non-array-like type [receiverClass]
- dynamic method [{}, {}/{}] not found
- Illegal list shortcut value [{}].
- dynamic getter [{}, {}] not found
- Illegal list shortcut value [name].
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/9e8733c3c990d55c.
Report an issue: GitHub.