{"record":{"id":"7e3f3bef99a8a44a","repo":"elastic/elasticsearch","slug":"dynamic-setter-receiverclass-name-not-found","errorCode":null,"errorMessage":"dynamic setter [receiverClass, name] not found","messagePattern":"dynamic setter \\[receiverClass, name\\] not found","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java","lineNumber":714,"sourceCode":"\n        // special case: maps, and lists\n        if (Map.class.isAssignableFrom(receiverClass)) {\n            // maps allow access like mymap.key\n            // wire 'key' as a parameter, its a constant in painless\n            return MethodHandles.insertArguments(MAP_PUT, 1, name);\n        } else if (List.class.isAssignableFrom(receiverClass)) {\n            // lists allow access like mylist.0\n            // wire '0' (index) as a parameter, its a constant. this also avoids\n            // parsing the same integer millions of times!\n            try {\n                int index = Integer.parseInt(name);\n                return MethodHandles.insertArguments(LIST_SET, 1, index);\n            } catch (final NumberFormatException exception) {\n                throw new IllegalArgumentException(\"Illegal list shortcut value [\" + name + \"].\");\n            }\n        }\n\n        throw new IllegalArgumentException(\"dynamic setter [\" + typeToCanonicalTypeName(receiverClass) + \", \" + name + \"] not found\");\n    }\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        }","sourceCodeStart":696,"sourceCodeEnd":732,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java#L696-L732","documentation":"Def.lookupSetter terminal fallback: after Map and List special cases, if no whitelisted field or setX() method matches the name on the receiver class, it throws 'dynamic setter [type, name] not found'. This is the assignment counterpart to the getter-not-found error.","triggerScenarios":"A Painless script writes x.someField = value on a 'def' receiver whose runtime class has no whitelisted settable field or setter method for 'someField'. Examples: assigning to a read-only field, a non-existent property, or a private field.","commonSituations":"Trying to mutate an immutable wrapper (e.g. a String or boxed primitive). Setting a doc field directly (not allowed — docs are read-only in most contexts). Property name typo. Receiver resolved to a type without a setter.","solutions":["Verify the field/setter is whitelisted and settable for the runtime receiver class.","Doc/_source fields are generally read-only in scripts; use ctx or params for mutable maps instead.","Type the receiver concretely to surface the missing setter at compile time.","Check for typos and read-only semantics."],"exampleFix":"// before\ndoc['price'].value = 10; // doc fields are read-only\n// after\nctx._source.price = 10;","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// For update-by-query, write to ctx._source (a Map); never to doc fields or scalars.\n// Type mutable accumulators as List/Map explicitly.","tryCatchPattern":"// On 'dynamic setter [..., name] not found', tell the author the field is read-only or absent; suggest ctx._source or a params Map.","preventionTips":["Use ctx._source for source mutations; doc fields are read-only.","Static-type receivers to surface missing setters at compile time.","Avoid assigning to immutable wrappers."],"tags":["painless","script","dynamic-dispatch","def","setter","runtime"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}