elastic/elasticsearch · error · NullPointerException
cannot access method/field [name] from a null def reference
Error message
cannot access method/field [name] from a null def reference
What it means
In def mode, every method invocation and field access goes through a guard that checks whether the receiver is null. The checkNull guard fires a NullPointerException with the method/field name when the receiver is null, because there is no class to dispatch against. This provides a clearer diagnostic than a raw NPE from the JVM.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java:143
this.functions = functions;
this.constants = constants;
this.methodHandlesLookup = methodHandlesLookup;
this.name = name;
this.flavor = flavor;
this.args = args;
this.depth = initialDepth;
MethodHandle fallback = FALLBACK.bindTo(this).asCollector(Object[].class, type.parameterCount()).asType(type);
setTarget(fallback);
}
/**
* guard method to give a more descriptive error message when a def receiver is null
*/
static Class<?> checkNull(Object receiver, String name) {
if (receiver == null) {
throw new NullPointerException("cannot access method/field [" + name + "] from a null def reference");
}
return receiver.getClass();
}
/**
* guard method for inline caching: checks the receiver's class is the same
* as the cached class
*/
static boolean checkClass(Class<?> clazz, Object receiver) {
return receiver != null && receiver.getClass() == clazz;
}
/**
* Does a slow lookup against the whitelist.
*/
private MethodHandle lookup(int flavorValue, String nameValue, Class<?> receiver) throws Throwable {
return switch (flavorValue) {View on GitHub (pinned to db6a809a66)
Solutions
- Null-check before any method or field access: `if (x != null) { def upper = x.toUpperCase(); }`
- Check field existence first: use `doc.containsKey('field')` or `doc['field'].size() != 0` before accessing the value.
- Provide a default: `def x = doc['field'].value; if (x == null) { x = 'default'; }`
- Avoid def for fields known to be absent; use typed accessors that return Optional-like semantics.
Example fix
// before
def name = doc['display_name'].value;
def upper = name.toUpperCase();
// after
def name = doc['display_name'].value;
if (name != null) {
def upper = name.toUpperCase();
} else {
def upper = '';
} Defensive patterns
Strategy: validation
Validate before calling
// Painless: null-check before any method/field access on a def value
def x = doc['optional_field'].value;
if (x != null) {
def result = x.toUpperCase();
} else {
def result = '';
} Type guard
// Painless null guard
def safeAccess(def value, def defaultValue) {
return value != null ? value : defaultValue;
} Prevention
- Always check `doc['field'].size() != 0` or `doc.containsKey('field')` before accessing field values that may be absent.
- Establish a null-check convention for every def-typed variable derived from document fields.
- Use explicit types (e.g., String, int) instead of def so missing fields surface as a compile-time mismatch rather than a runtime NPE.
When it happens
Trigger: A Painless script calls a method or accesses a field on a def variable that is null at runtime. Example: `def x = doc['optional_field'].value; def upper = x.toUpperCase();` where optional_field does not exist in the document, causing value to be null.
Common situations: Accessing a document field that is missing from some documents (Painless returns null for absent fields in def mode). Chaining calls on the result of a map lookup whose key may not exist. Processing heterogeneous documents where fields are conditionally present.
Related errors
- Cannot iterate over [receiverClass]
- script allocation limit exceeded: allocation of [{}] bytes b
- dynamic method [{}, {}/{}] not found
- Illegal list shortcut value [{}].
- dynamic getter [{}, {}] not found
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/6edc350391a679b7.
Report an issue: GitHub.