oracle/graal · error · IllegalArgumentException

Expected an EspressoExternalResolvedJavaField, got

Error message

Expected an EspressoExternalResolvedJavaField, got {}

What it means

EspressoExternalVMAccess.writeField(field, receiver, value) requires an EspressoExternalResolvedJavaField because only that class exposes the guest field Value needed to perform the reflective store. Passing a field implementation from another JVMCI backend makes the write impossible, so it fails fast with IllegalArgumentException instead of silently writing to the wrong target.

Solutions

  1. Resolve the field on an Espresso-resolved type so you get an EspressoExternalResolvedJavaField.
  2. Check field instanceof EspressoExternalResolvedJavaField (or owns(field)) before writing; use the owning provider otherwise.
  3. Avoid mocking ResolvedJavaField in tests; use the real Espresso meta access.

Example fix

// before
vmAccess.writeField(field, receiver, value);

// after
if (vmAccess.owns(field)) {
    vmAccess.writeField(field, receiver, value);
} else {
    foreignAccess.writeField(field, receiver, value);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(field instanceof EspressoExternalResolvedJavaField)) {
    // route to the owning provider's write path
}

Type guard

static boolean isEspressoField(ResolvedJavaField f) {
    return f instanceof EspressoExternalResolvedJavaField;
}

Try / catch

catch (IllegalArgumentException e) with 'Expected an EspressoExternalResolvedJavaField' -> re-resolve the field on the Espresso type and retry.

Prevention

When it happens

Trigger: Calling vmAccess.writeField() with a ResolvedJavaField resolved through the host HotSpot provider or a hand-rolled/stub field object.

Common situations: Snippet parameter patching and foreign-object initialization that mix providers; test doubles implementing ResolvedJavaField; cross-context field writes in polyglot embeddings.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/fdf79d25e3470997. Report an issue: GitHub.

Appendix: source

Thrown at espresso-compiler-stub/src/com.oracle.truffle.espresso.vmaccess/src/com/oracle/truffle/espresso/vmaccess/EspressoExternalVMAccess.java:524

    }

    @Override
    public boolean owns(ResolvedJavaField value) {
        return value instanceof Element;
    }

    @Override
    public JavaConstant invoke(ResolvedJavaMethod method, JavaConstant receiver, JavaConstant... arguments) {
        if (!(method instanceof EspressoExternalResolvedJavaMethod espressoMethod)) {
            throw new IllegalArgumentException("Expected an EspressoExternalResolvedJavaMethod, got " + safeGetClass(method));
        }
        return espressoMethod.invoke(receiver, arguments);
    }

    @Override
    public void writeField(ResolvedJavaField field, JavaConstant receiver, JavaConstant value) {
        if (!(field instanceof EspressoExternalResolvedJavaField espressoField)) {
            throw new IllegalArgumentException("Expected an EspressoExternalResolvedJavaField, got " + safeGetClass(field));
        }
        espressoField.writeValue(receiver, value);
    }

    @Override
    public JavaConstant asArrayConstant(ResolvedJavaType componentType, JavaConstant... elements) {
        if (!(componentType.getArrayClass() instanceof EspressoExternalResolvedArrayType arrayType)) {
            throw new IllegalArgumentException("Invalid component type");
        }
        EspressoResolvedJavaType elementalType = arrayType.getElementalType();
        Value array;
        boolean isPrimitiveArray;
        int dimensions = arrayType.getDimensions();
        if (elementalType instanceof EspressoExternalResolvedInstanceType elementalInstanceType) {
            array = invokeJVMCIHelper("newObjectArray", elementalInstanceType.getMetaObject(), dimensions, elements.length);
            isPrimitiveArray = false;
        } else {
            JavaKind javaKind = elementalType.getJavaKind();

View on GitHub (pinned to a66e9ccd1d)