oracle/graal · error · IllegalArgumentException
For static fields, the receiver argument must be null
Error message
For static fields, the receiver argument must be null
What it means
Thrown by HostVMAccess.writeField when writing a static field with a non-null receiver constant. Static field access needs no object, so passing a receiver is a caller contract violation, mirroring the equivalent rule in invoke for static methods.
Source
Thrown at compiler/src/jdk.graal.compiler.hostvmaccess/src/jdk/graal/compiler/hostvmaccess/HostVMAccess.java:227
if (cause instanceof HostProxyExceptionImpl) {
throw new InvocationException(cause.getCause());
}
throw new InvocationException(snippetReflection.forObject(cause), cause);
} catch (IllegalAccessException e) {
throw new RuntimeException("Should not reach here", e);
}
}
@Override
public void writeField(ResolvedJavaField field, JavaConstant receiver, JavaConstant value) {
SnippetReflectionProvider snippetReflection = providers.getSnippetReflection();
Field reflectionField = snippetReflection.originalField(field);
makeAccessible(reflectionField);
var fieldKind = field.getJavaKind();
if (Modifier.isStatic(reflectionField.getModifiers())) {
if (receiver != null) {
throw new IllegalArgumentException("For static fields, the receiver argument must be null");
}
} else if (receiver == null) {
throw new NullPointerException("For instance fields, the receiver argument must not be null");
} else if (receiver.isNull()) {
throw new IllegalArgumentException("For instance fields, the receiver argument must not represent a null constant");
}
Object unboxedValue;
if (fieldKind.isObject()) {
unboxedValue = snippetReflection.asObject(reflectionField.getType(), value);
} else {
assert fieldKind.isPrimitive();
if (fieldKind != value.getJavaKind()) {
throw new IllegalArgumentException("Expected value kind " + fieldKind + " but got " + value.getJavaKind());
}
unboxedValue = value.asBoxedPrimitive();
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Pass null as receiver for static fields
- Branch on Modifier.isStatic(reflectionField.getModifiers()) — or field.isStatic() on the ResolvedJavaField — before building the receiver, exactly as the guard does
Example fix
// before hostVM.writeField(staticField, snippetReflection.forObject(holder), value); // throws // after JavaConstant receiver = field.isStatic() ? null : snippetReflection.forObject(holder); hostVM.writeField(staticField, receiver, value);
Defensive patterns
Strategy: validation
Validate before calling
if (field.isStatic() && receiver != null) {
throw new IllegalArgumentException("receiver must be null for static field " + field); Type guard
static boolean needsReceiver(ResolvedJavaField f) { return !f.isStatic(); } Try / catch
catch (IllegalArgumentException e) { drop the receiver for static fields and re-invoke } Prevention
- Branch on field.isStatic() before building the receiver constant
- Centralize field writes in a helper that owns the rule
- Update call sites when a field becomes static
When it happens
Trigger: Calling writeField(staticField, receiver, value) with any non-null JavaConstant as receiver, where reflectionField has the static modifier.
Common situations: Shared field-writing helper that always computes a receiver (forObject(holder)) regardless of staticness; refactor turning an instance field static without updating call sites.
Related errors
- For static methods or constructor, the receiver argument mus
- For instance fields, the receiver argument must not be null
- For instance fields, the receiver argument must not represen
- Expected value kind {} but got {}
- For instance methods, the receiver argument must not be null
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/5944a0e707858723.
Report an issue: GitHub.