{"record":{"id":"dc4bae4bc77832a7","repo":"elastic/elasticsearch","slug":"dynamic-getter-not-found","errorCode":null,"errorMessage":"dynamic getter [{}, {}] not found","messagePattern":"dynamic getter \\[(.+?), (.+?)\\] not found","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java","lineNumber":662,"sourceCode":"            // arrays expose .length as a read-only getter\n            return arrayLengthGetter(receiverClass);\n        } else 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_GET, 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_GET, 1, index);\n            } catch (NumberFormatException exception) {\n                throw new IllegalArgumentException(\"Illegal list shortcut value [\" + name + \"].\");\n            }\n        }\n\n        throw new IllegalArgumentException(\"dynamic getter [\" + typeToCanonicalTypeName(receiverClass) + \", \" + name + \"] not found\");\n    }\n\n    /**\n     * Looks up handle for a dynamic field setter (field store)\n     * <p>\n     * A dynamic field store for variable {@code x} of type {@code def} looks like:\n     * {@code x.field = y}\n     * <p>\n     * The following field stores are allowed:\n     * <ul>\n     *   <li>Whitelisted {@code field} from receiver's class or any superclasses.\n     *   <li>Whitelisted method named {@code setField()} from receiver's class/superclasses/interfaces.\n     *   <li>The value corresponding to a map key named {@code field} when the receiver is a Map.\n     *   <li>The value in a list at element {@code field} (integer) when the receiver is a List.\n     * </ul>\n     * <p>\n     * This method traverses {@code recieverClass}'s class hierarchy (including interfaces)\n     * until it finds a matching whitelisted setter. If one is not found, it throws an exception.","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java#L644-L680","documentation":"Def.lookupGetter, after exhausting Map and List special cases (and the integer-parse path for lists), throws 'dynamic getter [type, name] not found' as the terminal fallback. It means the receiver class is neither Map nor List, no whitelisted field named 'name' exists, and no whitelisted getX()/isX() method matches — the dot-access has no resolution.","triggerScenarios":"A Painless script reads x.someField on a 'def' receiver whose runtime class has no whitelisted field or getter for 'someField'. Examples: accessing a private field, a field removed in a version, or a property name typo.","commonSituations":"Accessing _source/doc field via wrong path. Property name mismatch after a mapping change. Expecting a Java bean property that isn't whitelisted. Receiver resolved to null or a wrapper type.","solutions":["Verify the field/getter name against the Painless API allowlist for the receiver's runtime class.","Use the documented doc-values access (doc['field'].value) for indexed fields rather than arbitrary object access.","Type the receiver concretely so missing access is a compile-time error with a clearer message.","Check for typos and case sensitivity (camelCase)."],"exampleFix":"// before\ndef v = doc['timestamp'];\nreturn v.millis; // not a whitelisted getter\n// after\nreturn doc['timestamp'].value.toEpochMilli();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Prefer concrete types or doc-values access: doc['field'].value over arbitrary def dot-access.\n// In tests, assert the field path resolves via the Painless allowlist before shipping the script.","tryCatchPattern":"// On 'dynamic getter [..., name] not found', show the author the allowlisted fields/getters for the receiver class.","preventionTips":["Use doc['field'].value for indexed fields rather than object property access.","Static-type receivers to move missing-access errors to compile time.","Watch for camelCase and version-removed fields."],"tags":["painless","script","dynamic-dispatch","def","getter","runtime"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}