{"record":{"id":"5c5c5e71be26d1df","repo":"elastic/elasticsearch","slug":"attempting-to-address-a-non-array-like-type-recei","errorCode":null,"errorMessage":"Attempting to address a non-array-like type [receiverClass] as an array.","messagePattern":"Attempting to address a non-array-like type \\[receiverClass\\] as an array\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java","lineNumber":733,"sourceCode":"    }\n\n    /**\n     * Returns a method handle to normalize the index into an array. This is what makes lists and arrays stored in {@code def} support\n     * negative offsets.\n     * @param receiverClass Class of the array to store the value in\n     * @return a MethodHandle that accepts the receiver as first argument, the index as second argument, and returns the normalized index\n     *   to use with array loads and array stores\n     */\n    static MethodHandle lookupIndexNormalize(Class<?> receiverClass) {\n        if (receiverClass.isArray()) {\n            return ArrayIndexNormalizeHelper.arrayIndexNormalizer(receiverClass);\n        } else if (Map.class.isAssignableFrom(receiverClass)) {\n            // noop so that mymap[key] doesn't do funny things with negative keys\n            return MAP_INDEX_NORMALIZE;\n        } else if (List.class.isAssignableFrom(receiverClass)) {\n            return LIST_INDEX_NORMALIZE;\n        }\n        throw new IllegalArgumentException(\n            \"Attempting to address a non-array-like type \" + \"[\" + receiverClass.getCanonicalName() + \"] as an array.\"\n        );\n    }\n\n    /**\n     * Returns a method handle to do an array store.\n     * @param receiverClass Class of the array to store the value in\n     * @return a MethodHandle that accepts the receiver as first argument, the index as second argument,\n     *   and the value to set as 3rd argument. Return value is undefined and should be ignored.\n     */\n    static MethodHandle lookupArrayStore(Class<?> receiverClass) {\n        if (receiverClass.isArray()) {\n            return MethodHandles.arrayElementSetter(receiverClass);\n        } else if (Map.class.isAssignableFrom(receiverClass)) {\n            // maps allow access like mymap[key]\n            return MAP_PUT;\n        } else if (List.class.isAssignableFrom(receiverClass)) {\n            return LIST_SET;","sourceCodeStart":715,"sourceCodeEnd":751,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java#L715-L751","documentation":"Def.lookupIndexNormalize returns a MethodHandle that normalizes a bracket index (supports negative offsets). It handles arrays, Maps (noop normalize), and Lists (LIST_INDEX_NORMALIZE). For any other receiverClass — a non-array, non-Map, non-List type — it throws 'Attempting to address a non-array-like type [...] as an array', using receiverClass.getCanonicalName().","triggerScenarios":"A Painless script uses bracket index access x[i] on a 'def' variable whose runtime class is not an array, Map, or List — e.g. a String, a number, or a custom object. Negative-index normalization is requested but the type can't support indexing at all.","commonSituations":"Assuming String supports char indexing (it doesn't in Painless def dispatch). Indexing into a scalar or a wrapper type. Runtime type resolving to an unexpected class.","solutions":["Confirm the receiver is an array, List, or Map before bracket access.","For Strings, use whitelisted methods (charAt, substring) instead of indexing.","Type the variable concretely or guard with an instanceof check before indexing.","Validate params shape before the script runs."],"exampleFix":"// before\ndef s = 'hello';\nreturn s[0]; // String is not array-like\n// after\nreturn s.charAt(0);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Before bracket-read on a def value, narrow the type\nfunction isArrayLike(v) {\n  return Array.isArray(v) || v instanceof Map || Array.isArray(v); // JS analogue; in Java: v instanceof List || Map || array\n}\n// if (!isArrayLike(x)) throw new Error('Cannot index into non-array-like type');","tryCatchPattern":"// On 'Attempting to address a non-array-like type', advise the author to use String.charAt/substring or to verify the value is a List/Map/array.","preventionTips":["Use whitelisted String methods (charAt, substring) instead of indexing Strings.","Confirm receiver is array/List/Map before bracket access.","Static-type or instanceof-guard def values before indexing."],"tags":["painless","script","dynamic-dispatch","def","indexing","runtime"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}